Jump to content

[4.6 Beta] World Pick Can Fail


Recommended Posts

Hello,

After updating my project to 4.6, I've noticed that the picking system seems to be not as accurate as the 4.5 release. I've uploaded my project in full. Launch the player.map and look around near the edges of walls and floors. The axis crosshair will vanish. Pressing Mouse one will spawn an object at the calculated pick. Compile this with 4.5, and it works as expected.

The picking operations are under Game.cpp while the rest of the game is in Lua.

This may have to do with a previous update from December.

Quote

A new build is available on the beta branch. This changes the model picking system to use a different raycasting implementation under-the-hood. Sphere picking (using a radius) will also now correctly return the first hit triangle. You will also notice much faster loading times when you load up a detailed model in the editor!

 

Cyclone.zip

Cyclone - Ultra Game System - Component PreprocessorTex2TGA - Darkness Awaits Template (Leadwerks)

If you like my work, consider supporting me on Patreon!

Link to comment
Share on other sites

5 minutes ago, Josh said:

Where is the code located that is performing the pick?

The camera pick is done in CycloneCameraPlacement.Lua. This is the pick that causes the object (Cyclone) to be placed in walls.

function Script:UpdateTrace()
    local pickinfo=PickInfo()
    local p0 = self.entity:GetPosition(true)
	local p1 = Transform:Point(0, 0, 999, self.entity, nil)
    if self.entity.world:Pick(p0, p1, pickinfo, 0, true, Collision.LineOfSight) then
		self.target:SetPosition(pickinfo.position)
		self.target:AlignToVector(pickinfo.normal)

		self.box:SetColor(1,0,0) 
		self.box:Show()

		local hit =  window:MouseHit(1)
		local hitPos = pickinfo.position
		if Game:TestCyclonePlacement(pickinfo, self.box)==true then
			self.box:SetColor(0,1,0) 
			if hit==true then
				self:PlaceCyclone(pickinfo)
			end
		end
		hit = false
	end
end

Here is Game:TestCyclone located in Game.cpp for the correction placement. (To move the position away from corners)

bool Game::TestCyclonePlacement(PickInfo* pPickInfo, Entity* pTargetEntity)
	{
		if (!gamerules) InstallGameRules();

		// If there is no entity, return;
		if (pPickInfo->entity == nullptr) { return false; }

		// Check for surface
		if (pPickInfo->surface == nullptr) { return false; }

		//Check for a shape...
		if (pPickInfo->entity->GetShape() == nullptr) { return false; }

		// Check to see if it's CSG.
		if (pPickInfo->entity->GetClass() != Object::ModelClass)
		{
			return false;
		}
		else if (pPickInfo->entity->GetClass() == Object::ModelClass)
		{
			auto cast = static_cast<Model*>(pPickInfo->entity);
			if (cast->collapsedfrombrushes == false)
				return false;
		}

		// Test the material.
		if (CanPlaceOnSurface(pPickInfo->surface->GetMaterial()) == false)
		{
			return false;
		}

		// The target entity should be a pivot or something.
		// Basicly, the pivot position is where the cyclone is actually going to spawn at.
		if (pTargetEntity != NULL)
		{
			pTargetEntity->SetPosition(pPickInfo->position + pPickInfo->normal * 0.1);
			pTargetEntity->SetRotation(0, 0, 0);
			pTargetEntity->AlignToVector(pPickInfo->normal);

			float x = 0;
			float y = 0;

			PickInfo Pickinfo;
			auto world = World::GetCurrent();
			float distance = 0.64;
			float radius = 0;
			Vec3 tracetest;

			tracetest = Transform::Point(0, distance, 0, pTargetEntity, nullptr);
			if (world->Pick(pTargetEntity->GetPosition(false), tracetest, Pickinfo, radius, true, COLLISION_CYCLONEBUMPER))
			{
				y = -distance + MakePositve(pTargetEntity->GetPosition(false).DistanceToPoint(Pickinfo.position));
			}

			tracetest = Transform::Point(0, -distance, 0, pTargetEntity, nullptr);
			if (world->Pick(pTargetEntity->GetPosition(false), tracetest, Pickinfo, radius, true, COLLISION_CYCLONEBUMPER))
			{
				y = distance - MakePositve(pTargetEntity->GetPosition(false).DistanceToPoint(Pickinfo.position));
			}

			tracetest = Transform::Point(-distance, 0, 0, pTargetEntity, nullptr);
			if (world->Pick(pTargetEntity->GetPosition(false), tracetest, Pickinfo, radius, true, COLLISION_CYCLONEBUMPER))
			{
				x = distance - MakePositve(pTargetEntity->GetPosition(false).DistanceToPoint(Pickinfo.position));
			}

			tracetest = Transform::Point(distance, 0, 0, pTargetEntity, nullptr);
			if (world->Pick(pTargetEntity->GetPosition(false), tracetest, Pickinfo, radius, true, COLLISION_CYCLONEBUMPER))
			{
				x = -distance + MakePositve(pTargetEntity->GetPosition(false).DistanceToPoint(Pickinfo.position));
			}

			pTargetEntity->Move(x, y, 0);
			//pTargetEntity->AlignToVector(pPickInfo->normal);

			tracetest = Transform::Point(0, 0, -0.5, pTargetEntity, nullptr);
			if (world->Pick(pTargetEntity->GetPosition(false), tracetest, Pickinfo, 0, true, COLLISION_CYCLONEBUMPER) == false)
			{
				return false;
			}
		}

 

 

Cyclone - Ultra Game System - Component PreprocessorTex2TGA - Darkness Awaits Template (Leadwerks)

If you like my work, consider supporting me on Patreon!

Link to comment
Share on other sites

  • Josh locked this topic
Guest
This topic is now closed to further replies.
 Share

×
×
  • Create New...