Archive 19/01/2023.

Getting the world position of a vertex

HaeferlKaffee

I’m trying to create an effect that requires the world position, or at least position relative to node, of a random vertex on a mesh’s surface

I’m currently using this:

		Geometry* geom = ((AnimatedModel*)adjNode->GetComponent<AnimatedModel>())->GetLodGeometry(0, 0);

		const unsigned char* vertexData;
		const unsigned char* indexData;
		unsigned vertexSize;
		unsigned indexSize;
		const PODVector<VertexElement>* elements;

		geom->GetRawData(vertexData, vertexSize, indexData, indexSize, elements);

		// If data is bad:
		if (!vertexData || !elements || VertexBuffer::GetElementOffset(*elements, TYPE_VECTOR3, SEM_POSITION) != 0) {
			return;
		}
		const auto* vertices = (const unsigned char*)vertexData;

		// 16-bit indices ; short
		if (vertexSize == sizeof(unsigned short)) {
			surfacePoint = *(Vector3*)(&vertices[(short)Random(0, (int)vertexSize)]);

			// Rotate
			surfacePoint = adjNode->GetWorldRotation() * surfacePoint;
			// Scale
			surfacePoint *= adjNode->GetWorldScale();
			// Position
			surfacePoint = surfacePoint + adjNode->GetWorldPosition();

		}

Currently, the position of the vertex seems to be totally wrong. When I tried to create small spheres at each random location, they would group together at a point not on the mesh, and when enough spheres were created, they didn’t form the mesh they were supposed to be placed upon

Ideally, it should get the skinned position, i.e. use the animated model not the static mesh

SFrost

change:

surfacePoint = *(Vector3*)(&vertices[(short)Random(0, (int)vertexSize)]); 
// Rotate 
surfacePoint = adjNode->GetWorldRotation() * surfacePoint; 
// Scale 
surfacePoint *= adjNode->GetWorldScale(); 
// Position 
surfacePoint = surfacePoint + adjNode->GetWorldPosition();

to

surfacePoint = *(Vector3*)(&vertices[(short)Random(0, (int)vertexSize)]); 

// local to world
surfacePoint = adjNode->GetWorldTransform() * surfacePoint;
Modanung

Nodes even have a function for that: Node::LocalToWorld(const Vector3&)

SFrost

That’s a really helpful function for someone who’s not familiar with linear algebra.

HaeferlKaffee

Using the single world transform doesn’t help. I think it’s the way vertex positions are found, which I’ve mirrored from the Geometry GetHit function

Modanung

@SFrost Welcome to the forums, btw! :confetti_ball: :slight_smile:

SFrost

I didn’t realize that (Vector3 ) surfacePoint assignment was also incorrect.
Change it to:

surfacePoint = *(Vector3*)(&vertices[(short)Random(0, (int)geom->GetVertexCount()) * vertexSize]);

Thank you, Modanung.

Dave82
surfacePoint = *(Vector3*)(&vertices[(short)Random(0, (int)vertexSize)]);

This part doesnt seem right !

EDIT : Oh you just realised it too !

HaeferlKaffee

This is what I was looking for, thanks

I must’ve misunderstood how the GetHit function worked. Now to figure out how to get the skinned mesh…