Friday, 23 March 2007
private void dataGridView1_MouseMove(object sender, MouseEventArgs e)
if (e.Button == MouseButtons.Left)
// If the datagrid has any selected row, and the mouse moves outside the datagridView,
// start the drag.
if (this.dataGridView1.SelectedRows.Count > 0 &&
// Proceed with the drag and drop, passing in the list of selected rows. You can
// assign any DragDropEffect you´d like here.
This method determines that a dragging operation is being performed if the cursor gets out of the client rectangle of the grid, with the left button pressed (and any row selected).
It handles correctly a multi-select situation but it´s behavior is more "natural" if multiSelect is set to false, because while the cursor is inside the DataGrid, a drag will make the grid to select multiple rows. As soon as the cursor gets out the control, a Drag&Drop operation is started.
This is a verey simple and efficient way of handling this, but there are other possibilities.
Tipically, a windows application decides that a dragging operation is being performed if the mouse coursor travels (with the left button pressed) a certain distance, not necessarily out of the DataGridView like in the previous example. This minimum distance is a system configuration variable that can be found in: SystemInformation.DragSize.
Doing so is a more standard way and it also allows to drag and drop items inside the DataGridView. An easy way to handle this, is to keep track of a Rectangle defined at mouse down, with the dimensions of that DragSize. Some sample code:
private void dataGridView1_MouseDown(object sender, MouseEventArgs e)
// Get the index of the item the mouse is below.
DataGridView.HitTestInfo hInfo = this.dataGridView1.HitTest(e.X, e.Y);
// Will just handle if hitted a cell. You can test whatever kind of intersection you like here
if(hInfo.Type == DataGridViewHitTestType.Cell)
// The DragSize indicates the size that the mouse must move to consider a drag operation
Size dragSize = SystemInformation.DragSize;
// Create a rectangle using the DragSize, with the mouse position being
// at the center of the rectangle.
mMinDistanceRectangle = new Rectangle(
new Point(e.X - (dragSize.Width / 2), e.Y - (dragSize.Height / 2)), dragSize);
// Reset the rectangle if the mouse is not over an item in the ListBox.
mMinDistanceRectangle = Rectangle.Empty;
So, in the MouseMove event, you will want to test if the mouse is outside of that rectangle to start a Drag&Drop. Something like this:
if (mMinDistanceRectangle != Rectangle.Empty &&
!mMinDistanceRectangle .Contains(e.X, e.Y))
Hope this helps.
Thursday, 8 March 2007
Put in the Mesh class all the info wee need
Very much like we did in the Custom Content Processing post, we are going to use the “Tag” property of a mesh to store what we want, which in this case is something like this:
When VisualStudio passes every model through our ContentProcessor, it will write the model´s data to an XNB file. When it finds a MeshData object, will search for a writer that is able to serialize it, so we have to write our custom ContentTypeWriter for the MeshData class:
In a similar way, when the ContentPipeline tries to read back the XNB file, it will search for a deserializer for the type MeshData, so we have to write our own ContentTypeReader:
Finally, our Custom Content Processor that fills up the MeshData objects for each model goes through it:
Note: some parts taken from ZiggyWare:
In the next chapter will focus on the Collision Detection implementation using all this info. Cheers !
Tuesday, 6 March 2007
Accurate collision detection
( I assume here that you´ve read my post about Custom Content Processing: http://graphicdna.blogspot.com/2007/02/xna-customizing-content-processing.html )
A more accurate collision model is sometimes needed. The best is to develop a library of methods to test between meshes and rays, spheres, boxes, etc. How we do that?
Probably, you already incluye in your engine a system memory copy of your geometry. The problem is that there´s no direct access to content created with the WriteOnly flag in XNA, so you cannot create that sysmem copy at load time.
The solution is to make a custom content processor that stores that copy of the geometry at build time, where there´s still access to it. We made a simple example of something similar in the post mentioned above, but now we need more...
In the next post, I´ll show how to create a Custom Content Processor designed to store all the info needed for collision detection.
Monday, 5 March 2007
If you want to see an introductory post to Collision Detection, check out this one: http://graphicdna.blogspot.com/2007/02/3d-intersection-concepts-and.html
XNA collision detection
In D3D there´s a method called Mesh.Intersect that performs a Mesh-Ray intersection test. Many people thinks this method does some kind of optimized "magic" to test for intersection, but in fact it just loops throught all the triangles of the mesh doing a triangle-ray intersect, keeping track of the closest collision point. In XNA, there´s not such a method, and we will have to do it on our own. To do so, we will also have to deal with Custom Content Processing.
Simple Collision Detection
Before we go into a Mesh.Intersect() method, it´s a good idea to point out that XNA does include simple intersection tests for simplification shapes like: Bounding Spheres, AABB (Axis Aligned Bound Box), Planes, Rays, and any combination of them.
Using those tests, almost any kind of game-like intersection can be achieved. You must remember that a Mesh-Whatever intersection is expensive (depending in the number of polygons, of course), and should be left for special cases in which a very high intersection accuracy is needed. So, its usually preferred to aproximate a complex geometry by a bunch of spheres or boxes, than using the real triangles.
There´s a very good post at Sharky´s blog about XNA collisions, specially focused in approximating generic shapes with bounding spheres.
You can find it here: http://sharky.bluecog.co.nz/?p=119
Will continue tomorrow.
Thursday, 1 March 2007
It shows some of the newest environments available in the simulator. The link:
Hope you like it !