Jump to content

Model::IsCollapsedBrush()


reepblue
 Share

Recommended Posts

In Cyclone, I used the exposed Model::collapsedfrombrushes member as a first check to identify if the entity was a static brush. If this was false, that meant I was looking at a model loaded from disk which my placement system ignored completely.

I understand you not wanting to expose this member in Ultra Engine, but please make a return function like so:

const bool Model::IsCollapsedBrush()
{
	return collapsedfrombrushes;
}

Thanks.

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

Can you explain more what you are doing that requires this? It's just that there may be other geometry in the future that overlaps with this functionality, and would require an additional special case solution, so maybe there is a better way.

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

On 8/24/2022 at 2:23 AM, Josh said:

Can you explain more what you are doing that requires this? It's just that there may be other geometry in the future that overlaps with this functionality, and would require an additional special case solution, so maybe there is a better way.

The very first check my pick system did was check if the surface was a static brush or a model. This was mostly done as I wanted a quick condition to prevent players putting cyclones on models Also in Leadwerks, you had to obtain the material differently based if it was a collapsed brush, uncollapsed brush, or a loaded model. 

Just having a way to sort what's a model and what is world geometry is pretty much what I need and that bool members worked well for me.

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

I do this because within Leadwerks, I can count on the geometry being simple and static. Reflection on this, I'm now thinking that I could have probably get away with using material flags if I had that option. I used the roughness value in my game to check if the surface could hold a cyclone or not. I've never got to counting polys or checking the face size as everything I tried was really slow.  

Again, this was the very first check I implemented, and it stopped 80% of unwanted successful placements.

Real production code example.

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
const bool CanCycloneBePlaced(Entity* pEntity)
{
	if (pEntity == NULL)
		return false;

	// Quick force placement, ignores all other rules!
	if (String::Int(pEntity->GetKeyValue("force_cyclone_placement")) != 0)
		return true;

	if (pEntity->GetClass() == Object::ModelClass)
	{
		// Only allow placement on Models if it's collapsed CSG.
		auto cast = static_cast<Model*>(pEntity);
		if (cast->collapsedfrombrushes == false)
			return false;
	}

	return true;
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
const bool CanPlaceCycloneOnSurface(Leadwerks::Surface* pSurface)
{
	if (pSurface == nullptr)
		return false;

	auto material = pSurface->GetMaterial();

	if (material == nullptr)
		return false;

	if (material->GetBlendMode() != Blend::Solid)
		return false;

	if (IsReflectiveSurface(material))
		return false;

	return true;
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
const bool CanPlaceCycloneOnFace(Leadwerks::Face* pFace)
{
	if (pFace == NULL)
		return false;

	if (pFace->surface != NULL)
	{
		if (!CanPlaceCycloneOnSurface(pFace->surface))
			return false;
	}

	return true;
}

const bool CanPlace(PickInfo pPickInfo)
{
	if (pPickInfo.entity == NULL)
		return false;

	// Bail early if it's a platform.
	if (IsPlatform(pPickInfo.entity, pPickInfo.normal) && pPickInfo.entity->GetMass() == 0)
	{
		return true;
	}

	if (pPickInfo.entity->GetClass() == Object::ModelClass)
	{
		if (pPickInfo.surface == NULL)
			return false;

		if (!CanPlaceCycloneOnSurface(pPickInfo.surface))
			return false;

		if (!CanCycloneBePlaced(pPickInfo.entity))
			return false;
	}
	else if (pPickInfo.entity->GetClass() == Object::BrushClass)
	{
		if (!CanPlaceCycloneOnFace(pPickInfo.face))
			return false;
	}

	// Do the volume test last as it's another aabb check.
	return !IsPointInNoCycloneVolume(pPickInfo.position);
}

 

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

I am sort of leaning towards turning collapsed brushes into a special type of entity, a BSPTree. The difference between a BSP tree and a model is the collision geometry corresponds 1:1 to the visible geometry, so it is possible to retrieve the material for a collided surface, for footsteps, decals, and maybe other things.

  • Like 3

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...