void Skeleton::Draw( DebugRenderer& rend )
{
    ColorRGBA color = ColorRGBA::Green;

    for( u32 i = 0; i < m_joint_count; ++i )
    {
        SkeletonJoint& joint = m_joints[i];

        Matrix4x4 bind_pose = joint.GetInvBindPose();
        bind_pose.InverseIt();

        Vec4 pos = bind_pose * Vec4(0.f, 0.f, 0.f, 1.f);
        rend.AddAxis(bind_pose, 0.5f);

        // draw parent-child connection (if applicable).
        if( joint.GetParentIndex() != (u32)-1 && joint.GetParentIndex() < m_joint_count )
        {
            SkeletonJoint& parent = m_joints[joint.GetParentIndex()];

            Matrix4x4 parent_bind_pose = parent.GetInvBindPose();
            parent_bind_pose.InverseIt();

            Vec4 parent_pos = parent_bind_pose * Vec4(0.f, 0.f, 0.f, 1.f);

            rend.AddLine(Vec3(pos.x, pos.y, pos.z), Vec3(parent_pos.x, parent_pos.y, parent_pos.z), color);
        }
    }
}
void LiquidFunDebugDraw::DrawParticles(const b2Vec2* centers, float32 radius,
        const b2ParticleColor* colors, int32 count) {
    DebugRenderer* debugRenderer = Renderer::getCurrent()->getDebugRenderer();
    for (int i = 0; i < count; ++i) {
        debugRenderer->queueCircle(centers[i], radius, PARTICLE_CIRCLE_SEGMENTS,
                b2ColorToRgba(colors[i], 0xFF));
    }
}
Beispiel #3
0
	void CompositeBody::DebugRender(const DebugRenderer& debugRenderer) {
		debugRenderer.SetWorldTransform(GetPosition(), GetAngle());
		for (size_t i = 0; i < m_shapes.size(); ++i) {
			m_shapes[i].DebugRender(debugRenderer);
		}
		debugRenderer.RenderWorldAxises();
		debugRenderer.ResetWorldTransform();
	}
//显示选中物体的包围盒
void ObjectPositionEditor::HandlePostRenderUpdate(StringHash eventType, VariantMap& eventData)
{
	EditorRoot* pEditorRoot = EditorRoot::Instance();
	DebugRenderer* debug = pEditorRoot->scene_->GetComponent<DebugRenderer>();
	if(debug == NULL)
		return;

	vector<Node*> nodes = pEditorRoot->GetUnionSelections();
	for(int i = 0;i < nodes.size();i ++)
	{
		Node* node = nodes[i];
		if(node->GetComponent<Skybox>() != NULL)
			continue;

		debug->AddNode(node,1.0f,false);

		const Vector<SharedPtr<Component> >& components = node->GetComponents();
		for(int j = 0;j < node->GetNumComponents();j ++)
		{
			Drawable* drawable = dynamic_cast<Drawable*>(components[j].Get());
			if(drawable != NULL)
			{
				debug->AddBoundingBox(drawable->GetWorldBoundingBox(),Color::WHITE,true);
			}
		}
	}

	//计算总的
	if(nodes.size() > 1)
	{
		BoundingBox allBox;
		for(int i = 0;i < nodes.size();i ++)
		{
			Node* node = nodes[i];
			if(node->GetComponent<Skybox>() != NULL)
				continue;

			const Vector<SharedPtr<Component> >& components = node->GetComponents();
			for(int j = 0;j < node->GetNumComponents();j ++)
			{
				Drawable* drawable = dynamic_cast<Drawable*>(components[j].Get());
				if(drawable != NULL)
				{
					allBox.Merge(drawable->GetWorldBoundingBox());
				}
			}
		}

		debug->AddBoundingBox(allBox,Color::BLUE,true);
	}

	if(CurrentHoverObject != NULL)
	{
		CurrentHoverObject->DrawDebugGeometry(debug,false);
	}
}
Beispiel #5
0
void Hypothesis::draw(DebugRenderer &renderer) const {
	printf("Belief::Hypothesis::draw(showFrame=%s, showPoints=%s)\n", appearance.showFrames ? "ON" : "OFF", appearance.showPoints ? "ON" : "OFF");
	if (appearance.showFrames || true)
		renderer.addAxes(sample.toMat34() * modelFrame, appearance.frameSize);

	size_t t = 0;
	if (appearance.showPoints || true) {
		for (Cloud::PointSeq::const_iterator i = points.begin(); i != points.end(); ++i) {
			Cloud::Point point = *i;
			//if (++t < 10) printf("Belief::Hypothesis point %d <%.4f %.4f %.4f>\n", t, point.x, point.y, point.z);
			Cloud::setColour(/*appearance.colour*/RGBA::RED, point);
			renderer.addPoint(Cloud::getPoint<Real>(point));
		}
	}
}
static void RenderCallback()
	{
	// Physics code
	if(gScene && !gPause)	
		{
		gScene->simulate(1.0f/60.0f);	//Note: a real application would compute and pass the elapsed time here.
		gScene->flushStream();
		gScene->fetchResults(NX_RIGID_BODY_FINISHED, true);
		}
	// ~Physics code
	
	// Clear buffers
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	// Setup camera
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(60.0f, (float)glutGet(GLUT_WINDOW_WIDTH)/(float)glutGet(GLUT_WINDOW_HEIGHT), 1.0f, 10000.0f);
	gluLookAt(Eye.x, Eye.y, Eye.z, Eye.x + Dir.x, Eye.y + Dir.y, Eye.z + Dir.z, 0.0f, 1.0f, 0.0f);
	
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	gDebugRenderer.renderData(*gScene->getDebugRenderable());	
#ifdef __PPCGEKKO__	
	char buf[256];
    sprintf(buf,"Press 1,2,+,-,a,HOME to drop boxes. Press b to shoot a box.\nArrows camera.\n" );

    GLFontRenderer::setScreenResolution(glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT));
	GLFontRenderer::setColor(0.9f, 1.0f, 0.0f, 1.0f);
	GLFontRenderer::print(0.01, 0.9, 0.036, buf, false, 11, true);   
#endif	
	glutSwapBuffers();
	}
void ProcessInputs()
{
    UpdateWheelShapeUserData();

    ProcessForceKeys();

	if (bSetCurrentMotorTorque1)
	{
		bSetCurrentMotorTorque1 = false;
		wheel1->setMotorTorque(gCurrentMotorTorque1);
		// Set motor torque #1 in HUD
		char ds[512];
		sprintf(ds, "Left wheel torque: %d", gCurrentMotorTorque1);
		hud.SetDisplayString(2, ds, 0.015f, 0.92f);
	}

	if (bSetCurrentMotorTorque2)
	{
		bSetCurrentMotorTorque2 = false;
		wheel2->setMotorTorque(gCurrentMotorTorque2);
		// Set motor torque #2 in HUD
		char ds[512];
		sprintf(ds, "Right wheel torque: %d", gCurrentMotorTorque2);
		hud.SetDisplayString(3, ds, 0.015f, 0.87f);
	}

    // Show debug wireframes
    if (bDebugWireframeMode) 
	{
		if (gScene)
		{
			gDebugRenderer.renderData(*gScene->getDebugRenderable());
		}
    }
}
void ProcessInputs()
{
	DisableAKey('t');
    ProcessForceKeys();

	UpdateJointMotorTarget();

	if (bReconfigureD6Joint)
	{
		bReconfigureD6Joint = false;
		gJointType = (gJointType+1)%gNumJointConfigurations; 
		ReconfigureD6Joint();
	}

	if (bToggleLowerActorGravity)
	{
		char ds[512];

        bToggleLowerActorGravity = false;
        if (capsule2->readBodyFlag(NX_BF_DISABLE_GRAVITY))
            capsule2->clearBodyFlag(NX_BF_DISABLE_GRAVITY);   
        else
            capsule2->raiseBodyFlag(NX_BF_DISABLE_GRAVITY);

		// Set lower actor gravity in HUD
		sprintf(ds, "Lower Actor Gravity: %s", gOnOffString[!capsule2->readBodyFlag(NX_BF_DISABLE_GRAVITY)]);
		hud.SetDisplayString(11, ds, 0.015f, 0.47f);
    }

    // Show debug wireframes
	if (bDebugWireframeMode)
	{
		if (gScene)  gDebugRenderer.renderData(*gScene->getDebugRenderable());
	}
}
void ProcessInputs()
{
    // Show debug wireframes
	if (bDebugWireframeMode)
	{
		if (gScene)  gDebugRenderer.renderData(*gScene->getDebugRenderable());
	}
}
void ProcessInputs()
{
    ProcessForceKeys();

    // Show debug wireframes
    if (bDebugWireframeMode && (0 != gScene))
		gDebugRenderer.renderData(*gScene->getDebugRenderable());
}
void GameApplication::HandlePostRenderUpdate(StringHash eventType, VariantMap& eventData)
{
    // If draw debug mode is enabled, draw viewport debug geometry. Disable depth test so that we can see the effect of occlusion
    if (drawDebug_)
	{
        GetSubsystem<Renderer>()->DrawDebugGeometry(false);
	}

	DebugRenderer* debug = scene_->GetComponent<DebugRenderer>();

	//4
	for(int i = 0;i < 5;i ++)
	{
		//横线
		debug->AddLine(Vector3(- 2,0,i - 2),Vector3(2,0,i - 2),Color::YELLOW);
		//竖线
		debug->AddLine(Vector3(i - 2,0,- 2),Vector3(i - 2,0,2),Color::GREEN);
	}
}
Beispiel #12
0
void GameMain::HandlePostRenderUpdate(StringHash eventType, VariantMap& eventData)
{
#if 0 // debug waypoints trigger

	DebugRenderer* debug = scene_->GetComponent<DebugRenderer>();
	
	if (world.flyingBot.aiWaypoints_.Size() > 1)
	for(int i=0; i < world.flyingBot.aiWaypoints_.Size()-1; ++i) 
	{
		debug->AddLine(world.flyingBot.aiWaypoints_[i]->GetWorldPosition(),world.flyingBot.aiWaypoints_[i+1]->GetWorldPosition(), Color(1.0f, 1.0f, 0.0f));

	}
	debug->AddLine(world.flyingBot.aiWaypoints_[0]->GetWorldPosition(),world.flyingBot.aiWaypoints_[world.flyingBot.aiWaypoints_.Size()-1]->GetWorldPosition(), Color(1.0f, 1.0f, 0.0f));


	if (world.flyingBot.botSplinePath_ != NULL)
		world.flyingBot.botSplinePath_->DrawDebugGeometry(debug, true);

#endif
}
void ProcessInputs()
{
	DisableAKey('t');
    ProcessForceKeys();

    // Show debug wireframes
	if (bDebugWireframeMode)
	{
		if (gScene)  gDebugRenderer.renderData(*gScene->getDebugRenderable());
	}
}
Beispiel #14
0
void Navigation::HandlePostRenderUpdate(StringHash eventType, VariantMap& eventData)
{
    // If draw debug mode is enabled, draw navigation mesh debug geometry
    if (drawDebug_)
        scene_->GetComponent<NavigationMesh>()->DrawDebugGeometry(true);
    
    // Visualize the start and end points and the last calculated path
    DebugRenderer* debug = scene_->GetComponent<DebugRenderer>();
    if (startPosDefined_)
        debug->AddBoundingBox(BoundingBox(startPos_ - 0.1f * Vector3::ONE, startPos_ + 0.1f * Vector3::ONE), Color::WHITE);
    if (endPosDefined_)
        debug->AddBoundingBox(BoundingBox(endPos_ - 0.1f * Vector3::ONE, endPos_ + 0.1f * Vector3::ONE), Color::WHITE);
    if (currentPath_.Size() > 1)
    {
        // Draw the path with a small upward bias so that it does not clip into the surfaces
        Vector3 bias = 0.05f * Vector3::UP;
        for (unsigned i = 0; i < currentPath_.Size() - 1; ++i)
            debug->AddLine(currentPath_[i] + bias, currentPath_[i + 1] + bias, Color::WHITE);
    }
}
void ProcessInputs()
{
    ProcessForceKeys();

    // Show debug wireframes
	if (bDebugWireframeMode)
	{
		glDisable(GL_LIGHTING);
		if (gScene)  gDebugRenderer.renderData(*gScene->getDebugRenderable());
		glEnable(GL_LIGHTING);
	}
}
void ProcessInputs()
{
    ProcessMoveKeys();

	MatchTarget();

    // Show debug wireframes
	if (bDebugWireframeMode)
	{
		if (gScene)  gDebugRenderer.renderData(*gScene->getDebugRenderable());
	}
}
void
InputDeviceTouch::InternalUpdate(InputDeltaState* delta)
{
	impl_->Update(delta);

	if ((manager_.IsDebugRenderingEnabled() || IsDebugRenderingEnabled())
		&& manager_.GetDebugRenderer())
	{
		DebugRenderer* debugRenderer = manager_.GetDebugRenderer();
		InputState* state = GetInputState();

		for (unsigned i = 0; i < TouchPointCount; ++i)
		{
			if (state->GetBool(Touch0Down + i*4))
			{
				const float x = state->GetFloat(Touch0X + i*4);
				const float y = state->GetFloat(Touch0Y + i*4);
				debugRenderer->DrawCircle(x, y, 0.03f);
			}
		}
	}
}
Beispiel #18
0
void Navigation::HandlePostRenderUpdate(StringHash eventType, VariantMap& eventData)
{
    // If draw debug mode is enabled, draw navigation mesh debug geometry
    if (drawDebug_)
        scene_->GetComponent<NavigationMesh>()->DrawDebugGeometry(true);

    if (currentPath_.Size())
    {
        // Visualize the current calculated path
        DebugRenderer* debug = scene_->GetComponent<DebugRenderer>();
        debug->AddBoundingBox(BoundingBox(endPos_ - Vector3(0.1f, 0.1f, 0.1f), endPos_ + Vector3(0.1f, 0.1f, 0.1f)),
            Color(1.0f, 1.0f, 1.0f));

        // Draw the path with a small upward bias so that it does not clip into the surfaces
        Vector3 bias(0.0f, 0.05f, 0.0f);
        debug->AddLine(jackNode_->GetPosition() + bias, currentPath_[0] + bias, Color(1.0f, 1.0f, 1.0f));

        if (currentPath_.Size() > 1)
        {
            for (unsigned i = 0; i < currentPath_.Size() - 1; ++i)
                debug->AddLine(currentPath_[i] + bias, currentPath_[i + 1] + bias, Color(1.0f, 1.0f, 1.0f));
        }
    }
}
void ProcessInputs()
{
    UpdateWheelShapeUserData();

    ProcessForceKeys();

	if (bSetCurrentSteerAngle)
	{
		bSetCurrentSteerAngle = false;
        wheel1->setSteerAngle(gCurrentSteerAngle);
		// Add front wheel steer angle to HUD
		char ds[512];
		sprintf(ds, "Front Wheel Steer Angle: %d", (int)(gCurrentSteerAngle*180.0/NxPi));
		hud.SetDisplayString(2, ds, 0.015f, 0.92f);
	}

	if (bSetCurrentMotorTorque)
	{
		bSetCurrentMotorTorque = false;
        wheel2->setMotorTorque(gCurrentMotorTorque);
        wheel3->setMotorTorque(gCurrentMotorTorque);
		// Add rear wheel motor torque to HUD
		char ds[512];
		sprintf(ds, "Rear Wheel Motor Torque: %d", gCurrentMotorTorque);
		hud.SetDisplayString(3, ds, 0.015f, 0.87f);
	}

	if (bSetCurrentBrakeTorque)
	{
		bSetCurrentBrakeTorque = false;
		wheel2->setBrakeTorque(gCurrentBrakeTorque);
		wheel3->setBrakeTorque(gCurrentBrakeTorque);				
		// Add rear wheel brake torque to HUD
		char ds[512];
		sprintf(ds, "Rear Wheel Brake Torque: %d", gCurrentBrakeTorque);
		hud.SetDisplayString(4, ds, 0.015f, 0.82f);
	}


    // Show debug wireframes
    if (bDebugWireframeMode) 
	{
		if (gScene)
		{
			gDebugRenderer.renderData(*gScene->getDebugRenderable());
		}
    }
}
void ProcessInputs()
{
    ProcessForceKeys();

	if (bReleaseRandomShape)
	{
		bReleaseRandomShape = false;
	    ReleaseRandomShape();
	}

    // Show debug wireframes
	if (bDebugWireframeMode)
	{
		if (gScene)  gDebugRenderer.renderData(*gScene->getDebugRenderable());
	}
}
void ProcessInputs()
{
    // Print profile results (if enabled)
	gPerfRenderer.render(gScene->readProfileData(true), glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT));

	if (gbThreadPolling)
	{
		// We must reset the polling threads so they are ready for the next run
		gPollingThreads.ResetPollForWork();
	}

    ProcessForceKeys();
    // Show debug wireframes
	if (bDebugWireframeMode)
	{
		if (gScene)  gDebugRenderer.renderData(*gScene->getDebugRenderable());
	}
}
void Display()
{
	//clear display buffers
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	//set the camera view
	SetupCamera();

	//display scene
	if (rendering_mode != RENDER_WIREFRAME)
		RenderActors(bShadows);
	if (debugRenderable)
		gDebugRenderer.renderData(*debugRenderable);

	

	//render HUD	
	hud.Render();

	glFlush();
	glutSwapBuffers();
}
void ProcessInputs()
{
    ProcessForceKeys();

	// Core dump
	if (bCoreDump)
	{
		bool ok = NXU::coreDump(gPhysicsSDK, fnameCD, NXU::FT_XML, true, false);
		if(ok) {
			printf("Output core dump successfully!\n");
		} else {
			printf("Output core dump failed!\n");
		}
		bCoreDump = false;
	}

	// Load core to core container
	if (bLoadCore)
	{
		if(gPhysicsCollection) {
			NXU::releaseCollection(gPhysicsCollection);
			gPhysicsCollection = NULL;
		}
		gPhysicsCollection = LoadCoreDump(fnameCD);
		if(!gPhysicsCollection) {
			printf("Unable to load the core dump, please first save a core dump.\n");
		}
		else
		{
			printf("Core dump has been loaded into container.\n");
		}
		bLoadCore = false;
	}

	// instantiate a core dump
	if(bInstantiateCore) {
		if(gPhysicsCollection) {
			if(gPhysicsSDK) {
				ReleasePhysicsSDK(gPhysicsSDK);
				gPhysicsSDK = CreatePhysics();
			}
			if(InstantiateCoreDump(gPhysicsSDK, gPhysicsCollection)) {
				if(gPhysicsSDK->getNbScenes()) {
					gScene = gPhysicsSDK->getScene(0);
					AddUserDataToActors(gScene);
					NxActor** actors = gScene->getActors();
					gSelectedActor = *actors;
					while(!IsSelectable(gSelectedActor))
					{
						gSelectedActor = *actors++;
					}
				}
				printf("Core dump instantiated\n");
			}
			else
			{
				printf("Error in instantiating the core dump\n");
			}
		}
		else
		{
				printf("Unable to instantiate the core dump with an empty container\n");
		}
		bInstantiateCore = false;
	}

    // Show debug wireframes
	if (bDebugWireframeMode)
	{
		if (gScene)  gDebugRenderer.renderData(*gScene->getDebugRenderable());
	}
}
Beispiel #24
0
	void PolygonShape::DebugRender(const DebugRenderer& debugRenderer) {
		debugRenderer.RenderWirePolygon(m_polygon);
	}
void EnemyEntity::UpdateCast()
{
    DebugRenderer* debug = GetScene()->GetComponent<DebugRenderer>();
    PhysicsWorld2D* physicsWorld = GetScene()->GetComponent<PhysicsWorld2D>();
    RigidBody2D* body = GetComponent<RigidBody2D>();

    /*cast ground*/
    Vector2 originpos = node_->GetPosition2D();
    Vector2 FinishC;
    Vector2 FinishD;

    if(!isLeft)
    {
        FinishC = originpos + Vector2(-0.60,-0.35);
        FinishD = originpos + Vector2(-0.60,0);
    }

    else
    {
        FinishC = originpos + Vector2(0.60,-0.35);
        FinishD = originpos + Vector2(0.60,0);
    }


    PhysicsRaycastResult2D RayCastC;
    physicsWorld->RaycastSingle(RayCastC, originpos , FinishC,1);
    if ( !RayCastC.body_ && body->GetLinearVelocity().y_ >= -0.05f)
    {
        SetReturn();
    }

    PhysicsRaycastResult2D RayCastD;
    physicsWorld->RaycastSingle(RayCastD, originpos , FinishD,1);
    if ( RayCastD.body_)
    {
        SetReturn();
    }
    /*end cast ground*/

    /*cast player*/
    if(!isBusy && !isCooldDown)
    {
        Node* target = GetScene()->GetChild("Player",false);
        if(target)
        {
            Vector2 targetpos = target->GetPosition2D();
            Vector2 direction = targetpos - originpos;
            direction.Normalize();
            Vector2 FinishT = originpos + Vector2(direction.x_*2.5f,direction.y_*2.5);
            PhysicsRaycastResult2D RayCastT;
            physicsWorld->RaycastSingle(RayCastT, originpos , FinishT, 4);
            if (RayCastT.body_)
            {
                Node* node = RayCastT.body_->GetNode();
                if(node->GetName() == "Player")
                {
                    if(direction.x_ < 0)
                        setRight();
                    else
                        setLeft();
                    SetAtack();
                }
            }

            debug->AddLine( Vector3(originpos.x_, originpos.y_,0),
                        Vector3(FinishT.x_, FinishT.y_,0),
                        Color(0, 1, 1, 1),
                        false );

        }

    }

    /*end castplayer*/
    debug->AddLine( Vector3(originpos.x_, originpos.y_,0),
                            Vector3(FinishC.x_, FinishC.y_,0),
                            Color(1, 0, 0, 1),
                            false );

    debug->AddLine( Vector3(originpos.x_, originpos.y_,0),
                            Vector3(FinishD.x_, FinishD.y_,0),
                            Color(1, 0, 0, 1),
                            false );

}
Beispiel #26
0
bool IK::Solve(Vector3 targetPos)
{
	//http://mrl.nyu.edu/~perlin/gdc/ik/ik.java.html

	//Get nodes
	Node* hip = effector_->GetParent()->GetParent();
	Node* knee = effector_->GetParent();

	// Get current world position for the 3 joints of the IK chain
	Vector3 hipPos = hip->GetWorldPosition(); // Thigh pos (hip joint)
	Vector3 kneePos = knee->GetWorldPosition(); // Calf pos (knee joint)
	Vector3 effectorPos = effector_->GetWorldPosition(); // Foot pos (ankle joint)

	// Pre IK Direction vectors
	Vector3 thighDir = kneePos - hipPos; // Thigh direction
	Vector3 calfDir = effectorPos - kneePos; // Calf direction	

	// Vectors lengths
	float A = Vector3(thighDir).Length();//length of hip to knee
	float B = Vector3(calfDir).Length();//length of knee to foot
	Vector3 P = hip->WorldToLocal(targetPos);//target at origin
	Vector3 D = hip->WorldToLocal(kneePos);//pre solve knee at origin
	//float limbLength = length1 + length2;
	//float lengthH = targetDir.Length();

	//PERLINS STUFF
	//bool test = Perlin(A,B,C,D);
	//GetSubsystem<DebugHud>()->SetAppStats("ik:", String(test) );
	//------
	Vector3 R;
	DefineM(P,D);
	R = Rot(Minv,P);
	//FIND D
	float c = R.Length();
    float d = Max(0.0f, Min(A, (c + (A*A-B*B)/c) / 2.0f));//FindD(A,B,R.Length());
    //FIND E
    float e = sqrtf(A*A-d*d);//FindE(A,d);
    Vector3 S = Vector3(d,e,0.0f);
    Vector3 Q = Rot(Mfwd,S);

    //Convert Q back to world space
    Vector3 worldQ = effector_->GetParent()->GetParent()->LocalToWorld(Q);

    //Get angles
    Vector3 tdn = thighDir.Normalized();
    Vector3 ntdn = Vector3(worldQ-hipPos).Normalized();
    Vector3 cdn = calfDir.Normalized();
    Vector3 ncdn = Vector3(targetPos-worldQ).Normalized();

    //Vector3 hipAxis = tdn.CrossProduct(ntdn); 
    //float hipAngle = tdn.Angle(ntdn);
    //Vector3 kneeAxis = cdn.CrossProduct(ncdn);
    //float kneeAngle = cdn.Angle(ncdn);

    //GetSubsystem<DebugHud>()->SetAppStats("ik:", String(hipAngle)+":"+String(kneeAngle) );

    //knee->SetWorldRotation(knee->GetWorldRotation() * Quaternion(kneeAngle,kneeAxis) );
	//hip->SetWorldRotation(hip->GetWorldRotation() * Quaternion(hipAngle,hipAxis) );
	//do top level first, then get new angle for lower level, since it might mangle it
	bool success = d > 0.0f && d < A;

	if(success)
	{
		Quaternion hipRot = Quaternion(tdn,ntdn);
		hip->Rotate(hipRot,TS_WORLD );
		knee->Rotate(Quaternion(cdn,ncdn)*hipRot.Inverse(),TS_WORLD );
	}

    if(drawDebug_)
    {
	    DebugRenderer* dbg = effector_->GetScene()->GetComponent<DebugRenderer>();
	    
	    /*dbg->AddLine(hipPos,hipPos+tdn,Color(0.0f,1.0f,0.0f),false);
    	dbg->AddLine(hipPos,hipPos+ntdn,Color(0.0f,0.0f,1.0f),false);
	    dbg->AddLine(kneePos,kneePos+cdn,Color(0.0f,1.0f,0.0f),false);
    	dbg->AddLine(kneePos,kneePos+ncdn,Color(0.0f,0.0f,1.0f),false);

    	dbg->AddSphere(Sphere(effectorPos,0.2f),Color(0.0f,1.0f,0.0f),false);
    	dbg->AddSphere(Sphere(targetPos,0.2f),Color(0.0f,0.0f,1.0f),false);*/
	    //at origin
	    /*dbg->AddSphere(Sphere(Vector3(),0.2f),Color(0.0f,0.0f,0.0f),false);//origin
	    dbg->AddSphere(Sphere(D,0.2f),Color(0.1f,0.0f,0.0f),false);//old elbow
	    dbg->AddSphere(Sphere(P,0.2f),Color(0.0f,1.0f,0.0f),false);//target
	    dbg->AddLine(Vector3(),P,Color(0.1f,0.1f,0.1f),false);

	    //show solve at origin
	    dbg->AddSphere(Sphere(Q,0.2f),Color(1.0f,0.0f,0.0f),false);
		dbg->AddLine(Vector3(),Q,Color(1.0f,0.0f,0.0f),false);
		dbg->AddLine(Q,P,Color(1.0f,0.0f,0.0f),false);*/

		//show solve at position
		dbg->AddSphere(Sphere(worldQ,0.2f),Color(1.0f,0.0f,0.0f),false);
		dbg->AddSphere(Sphere(targetPos,0.2f),Color(0.0f,1.0f,0.0f),false);
		dbg->AddLine(hipPos,worldQ,Color(1.0f,0.0f,0.0f),false);
		dbg->AddLine(worldQ,targetPos,Color(1.0f,0.0f,0.0f),false);
	}

    return success;

	
}