Jump to content

SpiderPig

Members
  • Posts

    2,340
  • Joined

  • Last visited

Posts posted by SpiderPig

  1. You use the plane like a Vec3.  The constructor can take three positions to define it, then you can use functions like GetNormal() and DistanceToPoint().

    I imagine the positions as forming a triangle, and the plane extending out from that in all directions.

    Vec3 p1 = Vec3(-1.0f, -1.0f, -1.0f);
    Vec3 p2 = Vec3(0.0f, 1.0f, 1.0f);
    Vec3 p3 = Vec3(1.0f, 0.0f, 0.0f);
    
    Plane plane = Plane(p1, p2, p3);
    Vec3 normal = plane.GetNormal();
    float distance = plane.DistanceToPoint(2, 1, 0);

    I'm not sure how to define it using the other constructors as shown in the example in Transform::Plane()

    • Like 1
  2. Here's my attempt so far at making my own character controller.  The reason for this is because I'm using multiple gravity directions in the same world and the current controller doesn't like gravity in any direction other than down the y axis.

    The problem I'm having is getting the controller to stay constrained to the up axis, when you move it with speed (shift key) you'll see that it drags across the terrain and bounces around.  I'm not sure how to correctly use the joints settings to stop this kind of movement.  Any help is appreciated.

    #include "App.h"
    
    using namespace Leadwerks;
    
    App::App() : window(NULL), context(NULL), world(NULL), camera(NULL) {}
    
    App::~App() { delete world; delete window; }
    
    float lookspeed = 0.1, looksmoothing = 0.5;
    Vec3 mousepos;
    
    float jointpos = 1;
    bool wireframe = false;
    Joint* joint;
    Entity* parent;
    
    Joint* k = nullptr;
    Entity* child;
    
    bool App::Start()
    {
    	window = Leadwerks::Window::Create();
    	context = Context::Create(window);
    	world = World::Create();
    	camera = Camera::Create();
    	camera->Move(0, 0, -4);
    	Light* light = DirectionalLight::Create();
    	light->SetRotation(35, 35, 0);
    
    	parent = Model::Box();
    	parent->SetColor(0.0, 0.0, 1.0);
    	parent->SetMass(1);
    	parent->SetGravityMode(false);
    
    	child = Model::Box();
    	child->SetColor(1.0, 0.0, 0.0);
    	child->SetShape(Shape::Box());
    	child->SetMass(1);
    	child->SetGravityMode(true);
    
    	k = Joint::Kinematic(0, 0, 0, parent);
    
    	joint = Joint::Slider(0, 0, 0, 0, 1, 0, child, parent);
    	joint->EnableLimits();
    	joint->SetLimits(-5, 5);
    	joint->SetMotorSpeed(100);
    
    	Model* mdl = Model::Load("Models\\Terrain.mdl");
    	mdl->SetScale(20, 20, 20);
    	mdl->SetPosition(0, -3, 0);
    
    	Shape* shp = Shape::PolyMesh(mdl->GetSurface(0));
    	mdl->SetShape(shp);
    
    	mousepos = window->GetMousePosition();
    	window->SetMousePosition(context->GetWidth() / 2, context->GetHeight() / 2);
    
    	return true;
    }
    
    bool App::Loop()
    {
    	if (window->Closed() || window->KeyDown(Key::Escape)) return false;
    	if (window->KeyHit(Key::F3) == true) { camera->GetDebugPhysicsMode() == true ? camera->SetDebugPhysicsMode(false) : camera->SetDebugPhysicsMode(true); }
    	if (window->KeyHit(Key::F4) == true) { camera->GetDebugEntityBoxesMode() == true ? camera->SetDebugEntityBoxesMode(false) : camera->SetDebugEntityBoxesMode(true); }
    	if (window->KeyHit(Key::F2) == true)
    	{
    		if (wireframe == true)
    		{
    			camera->SetDrawMode(0);
    			wireframe = false;
    		}
    		else
    		{
    			camera->SetDrawMode(2);
    			wireframe = true;
    		}
    	}
    
    	float cx = Math::Round(context->GetWidth() / 2);
    	float cy = Math::Round(context->GetHeight() / 2);
    	Vec3 mpos = window->GetMousePosition();
    	window->SetMousePosition(cx, cy);
    	mpos = mpos * looksmoothing + mousepos * (1 - looksmoothing);
    	float dx = (mpos.x - cx) * lookspeed;
    	float dy = (mpos.y - cy) * lookspeed;
    
    	Vec3 camrot = camera->GetRotation();
    	camrot.x += dy;
    	camrot.y += dx;
    	camera->SetRotation(camrot);
    	mousepos = mpos;
    
    	float _time = Time::GetSpeed();
    	float camspeed = 0.2f * _time;
    	if (window->KeyDown(Key::Shift) == true) { camspeed = camspeed * 5.0f; }
    	if (window->KeyDown(Key::W) == true) { camera->Move(0, 0, camspeed); }
    	else if (window->KeyDown(Key::S) == true) { camera->Move(0, 0, -camspeed); }
    	if (window->KeyDown(Key::A) == true) { camera->Move(-camspeed, 0, 0); }
    	else if (window->KeyDown(Key::D) == true) { camera->Move(camspeed, 0, 0); }
    	if (window->KeyDown(Key::T) == true) { camera->Move(0, camspeed, 0); }
    	else if (window->KeyDown(Key::G) == true) { camera->Move(0, -camspeed, 0); }
    
    	Vec3 p = parent->GetPosition(true);
    	Vec3 r = parent->GetRotation(true);
    	float speed = 0.1f;
    	if (window->KeyDown(Key::Shift) == true) { speed = 1.0f; }
    	if (window->KeyDown(Key::Up)) { k->SetTargetPosition(p.x, p.y, p.z + speed); }
    	if (window->KeyDown(Key::Down)) { k->SetTargetPosition(p.x, p.y, p.z - speed); }
    	if (window->KeyDown(Key::Left)) { k->SetTargetPosition(p.x - speed, p.y, p.z); }
    	if (window->KeyDown(Key::Right)) { k->SetTargetPosition(p.x + speed, p.y, p.z); }
    
    	//Jumping...?
    	joint->SetAngle(jointpos);
    	if (joint->MotorEnabled() == true)
    	{
    		joint->DisableMotor();
    	}
    	if (window->KeyHit(Key::Space))
    	{
    		joint->EnableMotor();
    	}
    
    	Leadwerks::Time::Update();
    	world->Update();
    	world->Render();
    
    	context->SetBlendMode(Blend::Alpha);
    	context->DrawText("Target position: " + String(jointpos), 0, 0);
    	context->DrawText("Current position: " + String(joint->GetAngle()), 0, 20);
    	context->DrawText("Motor enabled: " + String(joint->MotorEnabled()), 0, 40);
    	context->SetBlendMode(Blend::Solid);
    
    	context->Sync();
    
    	return true;
    }

     

    Other links;

    https://www.leadwerks.com/community/topic/17437-physics-constraints/

    Project.zip

  3. I've not created metal materials before but if not the "diffuse+normal+specular" shader it might be the "diffuse+normal+specular+env" shader, where texture5 is a cube map that the object will reflect, perhaps making it look more like metal.

  4. You would use Sin () and Cos () to find the x and y position.

    Is alpha a constant?  Like 90°?

    Do the red and blue positions vary in the third dimension as well? Or are you looking for the 2D position only of the black?

  5. #include "App.h"
    
    using namespace Leadwerks;
    
    App::App() : window(NULL), context(NULL), world(NULL), camera(NULL) {}
    
    App::~App() { delete world; delete window; }
    
    float jointpos = 1;
    bool wireframe = false;
    Joint* joint;
    Entity* parent;
    
    bool App::Start()
    {
    	window = Leadwerks::Window::Create();
    	context = Context::Create(window);
    	world = World::Create();
    	camera = Camera::Create();
    	camera->Move(0, 0, -4);
    	Light* light = DirectionalLight::Create();
    	light->SetRotation(35, 35, 0);
    
    	parent = Model::Box();
    	parent->SetColor(0.0, 0.0, 1.0);
    
    	Entity* child = Model::Box();
    	child->SetColor(1.0, 0.0, 0.0);
    	child->SetShape(Shape::Box());
    	child->SetMass(1);
    	child->SetFriction(0, 0);
    	child->SetGravityMode(true);
    
    	joint = Joint::Slider(0, 0, 0, 0, 1, 0, child, parent);
    	joint->EnableLimits();
    	joint->SetLimits(-3, 1);
    
    	Model* mdl = Model::Box();
    	mdl->SetScale(10, 0.1, 10);
    	mdl->SetPosition(0, -2, 0);
    
    	Shape* shp = Shape::Box();
    	mdl->SetShape(shp);
    
    	return true;
    }
    
    bool App::Loop()
    {
    	if (window->Closed() || window->KeyDown(Key::Escape)) return false;
    	if (window->KeyHit(Key::F3) == true) { camera->GetDebugPhysicsMode() == true ? camera->SetDebugPhysicsMode(false) : camera->SetDebugPhysicsMode(true); }
    	if (window->KeyHit(Key::F4) == true) { camera->GetDebugEntityBoxesMode() == true ? camera->SetDebugEntityBoxesMode(false) : camera->SetDebugEntityBoxesMode(true); }
    	if (window->KeyHit(Key::F2) == true)
    	{
    		if (wireframe == true)
    		{
    			camera->SetDrawMode(0);
    			wireframe = false;
    		}
    		else
    		{
    			camera->SetDrawMode(2);
    			wireframe = true;
    		}
    	}
    
    	if (window->KeyDown(Key::Up)) { parent->Move(0, 0, 0.1); }
    	if (window->KeyDown(Key::Down)) { parent->Move(0, 0, -0.1); }
    	if (window->KeyDown(Key::Left)) { parent->Move(-0.1, 0, 0); }
    	if (window->KeyDown(Key::Right)) { parent->Move(0.1, 0, 0); }
    
    	joint->SetAngle(jointpos);
    	if (window->KeyHit(Key::Space))
    	{
    		if (!joint->MotorEnabled())
    		{
    			joint->EnableMotor();
    		}
    		else
    		{
    			joint->DisableMotor();
    		}
    	}
    
    	Leadwerks::Time::Update();
    	world->Update();
    	world->Render();
    
    	context->SetBlendMode(Blend::Alpha);
    	context->DrawText("Target position: " + String(jointpos), 0, 0);
    	context->DrawText("Current position: " + String(joint->GetAngle()), 0, 20);
    	context->DrawText("Motor enabled: " + String(joint->MotorEnabled()), 0, 40);
    	context->SetBlendMode(Blend::Solid);
    
    	context->Sync();
    
    	return true;
    }

    Using the arrows keys to move the sliders parent around you can see that the child takes time to realign itself.  Is it possible to stop this delay?

  6. What's the best way to add physics constraints to a custom player controller?  For example, the cylinder shape is pulled toward gravity (which is not always straight down) then collides with an object, how do I stop little movements like sliding and twisting once it collides?

    As far as I can tell, the inbuilt character controller only slides if the slope is greater than max slope.  And when it moves around by key press it doesn't rotate left or right or jitter as it goes over various sloped polygons.

    Gravity is added like so in a different class to the controller;

    float _force = -9.8f;
    entity->AddForce(_gravity->gravityDirection.x * _force, _gravity->gravityDirection.y * _force, _gravity->gravityDirection.z * _force);		//gravityDirection is a normalized vector

    And so far for the controller I've been doing this to make it move;

    Vec3 _velocity = entity->GetVelocity(true);					//Get the current velocity
    Vec3 _gravityVelocity = _velocity.Multiply(upDirection);			//Find how much of the velocity is along the gravity vector
    Vec3 _otherVelocity = _velocity.Subtract(_gravityVelocity);			//Any remaining velocity other than gravity
    
    Vec3 _forwardVelocity = _forwardVector * move;					//A vector in front of the player and perpindicular to gravity
    Vec3 _strafeVelocity = _strafeVector * strafe;					//A vector that is the cross of gravity and the forward vector (out to the side)
    Vec3 _jumpVelocity = upDirection * jump;					//GravityDirection * -1.0f
    movementVector = _forwardVelocity + _strafeVelocity + _jumpVelocity;		//Find total movement vector (don't normalize, magnitude is speed)
    entity->SetVelocity((_velocity - _otherVelocity) + movementVector, true);	//Subtract othervelocity to get only what gravity is, then add any movemnt
    entity->SetOmega(0.0f, 0.0f, 0.0f, true);					//Been using this to reduce angular rotation, not perfect though

    The above code has issues still, but it's my attempt at constraining it along gravity unless needed to move.  This code isn't done in a physics hook, which I was wondering if that might be better?

    And here's a quick video showing the physic shape jittering.  It doesn't translate to the camera much at the moment but it does when the jitter is larger.  Also I can't move the shape along it's local axis because of the jitter and the random rotation that happens as a result of moving.

    https://youtu.be/ZA_UNsYCEQs

    Any thoughts on more accurate ways of constraining are appreciated :D

  7. Glad you got it working.  Your code at the moment is very inefficient.  You should structure it like this;

    ...	
    world->Render();
    
    
    //DRAW FPS
    context->SetBlendMode(Blend::Alpha);
    context->SetColor(1, 0, 0, 1);								//Use values 0.0 to 1.0
    context->DrawText("FPS : " + String(Time::UPS()), 10, 20);
    
    PickInfo pickInfo;
    bool success = world->Pick(rayCastFirst, rayCastEnd, pickInfo);
    if(success == true)
    {
          //DRAW LINE
          Vec3 firstPos = camera->Project(rayCastFirst);
          Vec3 lastPos = camera->Project(rayCastEnd); 
          context->DrawLine(firstPos.x, firstPos.y, lastPos.x, lastPos.y);
    
          //DRAW KEY VALUE
          context->SetColor(1, 1, 1, 1);
          context->DrawText(pickInfo.entity->GetKeyValue("Color"), 20, 40);
    }
    
    //set sphere to hit
    hitSphere->SetPosition((success == true) ? (pickInfo.position) : (rayCastFirst));
    
    context->SetBlendMode(Blend::Solid);
    context->Sync(true);
    
    ...

     

    • Thanks 2
  8. Ah I see it now, your doing a pick again but this time the sphere is in the way. Try setting the spheres pick mode to '0' I think it is... or what would be better is to do the check once.

    bool success = world->Pick(rayCastFirst, rayCastEnd, pickInfo, 0, true);
    
    //Now use pickInfo

     

    • Like 1
  9. This is probably more a question for Josh, but does anyone know how to use the CharacterController class by itself and not by using SetCollisionType() on an entity?

    I'm trying to create a controller and update forces on it myself, like so;

    //Create
    auto b = Model::Box();
    auto cont = CharacterController::Create(b);
    
    //Update
    cont->addForce(-1.0f,0.0f,0.0f);

     

  10. Can the gravity direction be changed on a per object basis rather than per world?  I'd like to change the direction for the character controller.  Would it be possible to turn off the world gravity and add forces to the controller object, or will this mess things up? ?

×
×
  • Create New...