[SOLVED] Weird picking problem

hello,

I’ve created my own GeomNode representing a box.
I can click on the box and recolor it to something else. I can also move the box around.
Note that this is not done via the “nodepath” but directly by rewriting the vertex buffer of my geomnode.

After this operation my geometry is displayed correctly in the position I’ve moved it to but I cannot pick the node anymore. The collision doesn’t seem to happen anymore.

Do I need to recompute the physics bounds or something similar ?

Normally, the correct way to modify a vertex buffer is to access the vertex buffer from the Geom first with nodePath.node()->modify_geom()->modify_vertex_data(). If you do this, it tells the Geom that you are moving vertices around, and that it therefore needs to invalidate caches and recompute its bounding volume.

If, instead, you keep a pointer to the vertex data after you created the Geom, and simply modify that pointer directly instead of re-obtaining it from the Geom, then the Geom has no way to know what you are doing beneath it and its cached values can become invalid.

David

this is how I rewrite the data

void cVertex::RewriteVertexGeom()
{
	LVector4f vertexColor = mbSelected ? LVector4f(0, 0, 1, 1.0f) : LVector4f(0, 1, 0, 1.0f);

	for (int j = 0; j < mVertexGeom->get_num_primitives(); ++j) 
	{ 
		PT(GeomPrimitive) prim = mVertexGeom->modify_primitive(j); 
		for (int p = 0; p < prim->get_num_primitives(); ++p) 
		{ 
			int start = prim->get_primitive_start(p); 
			int end = prim->get_primitive_end(p); 
			for (int i = start; i < end; ++i) 
			{ 
				int vertID = prim->get_vertex(i); 
				mVertices.set_row(vertID);
				mColors.set_row(vertID);

				LVector3f pos = gsVertOffsets[vertID] + mPosition;
				mVertices.set_data3f(pos);

				mColors.set_data4f(vertexColor);
			}
		}
	} 
}

and it’s called from here

void cVertex::SetPosition(LVector3f position)
{
	mPosition = position;
	RewriteVertexGeom();
}

this cVertex class is derived of GeomNode and can be added into the scenegraph.
It’s purpose is to keep a position and render a little box.

Where did you get the mVertexGeom pointer? Did you store it after creating it? That’s a similar problem. It’s also important to tell the GeomNode that you’re modifying its internal Geom object, by re-obtaining the Geom pointer each time you intend to change it with GeomNode::modify_geom().

Same problem with mVertices and mColors. You need to re-obtain them from the Geom pointer (which you re-obtained from the GeomNode).

David

these are the values I store within my class

	PT(Geom) mVertexGeom;
	PT(GeomVertexData) mVData;
	GeomVertexRewriter mVertices;
	GeomVertexRewriter mColors;

the reason why I did store these values is because the class is intended to be usable within the scenegraph and I thougt it shouldn’t really contain a NodePath for the “debug box” of my vertex - but rather the GeomNode which I’ve created for it.

I’ve modified my code as follows

void cVertex::RewriteVertexGeom()
{
	LVector4f vertexColor = mbSelected ? LVector4f(0, 0, 1, 1.0f) : LVector4f(0, 1, 0, 1.0f);

	PT(Geom) vertexGeom = modify_geom(0);

	for (int j = 0; j < vertexGeom->get_num_primitives(); ++j) 
	{ 
		PT(GeomPrimitive) prim = vertexGeom->modify_primitive(j); 
		for (int p = 0; p < prim->get_num_primitives(); ++p) 
		{ 
			int start = prim->get_primitive_start(p); 
			int end = prim->get_primitive_end(p); 
			for (int i = start; i < end; ++i) 
			{ 
				int vertID = prim->get_vertex(i); 
				mVertices.set_row(vertID);
				mColors.set_row(vertID);

				LVector3f pos = gsVertOffsets[vertID] + mPosition;
				mVertices.set_data3f(pos);

				mColors.set_data4f(vertexColor);
			}
		}
	} 
}

how can I re-obtain the mVertices and mColors ?

ok, I’ve modified my code further and it all works now.

void cAWVertex::RewriteVertexGeom()
{
	LVector4f vertexColor = mbSelected ? LVector4f(0, 0, 1, 1.0f) : LVector4f(0, 1, 0, 1.0f);

	PT(Geom) vertexGeom = modify_geom(0);
	
	PT(GeomVertexData) vData = vertexGeom->modify_vertex_data();
	GeomVertexRewriter vertices = GeomVertexRewriter(vData, "vertex");
	GeomVertexRewriter colors = GeomVertexRewriter(vData, "color");

	for (int j = 0; j < vertexGeom->get_num_primitives(); ++j) 
	{ 
		PT(GeomPrimitive) prim = vertexGeom->modify_primitive(j); 
		for (int p = 0; p < prim->get_num_primitives(); ++p) 
		{ 
			int start = prim->get_primitive_start(p); 
			int end = prim->get_primitive_end(p); 
			for (int i = start; i < end; ++i) 
			{ 
				int vertID = prim->get_vertex(i); 
				vertices.set_row(vertID);
				colors.set_row(vertID);

				LVector3f pos = gsBoxVertOffsets[vertID] + mPosition;
				vertices.set_data3f(pos);

				colors.set_data4f(vertexColor);
			}
		}
	} 
}