Problem
The sphere of the model is the smallest sphere of the complete model. In many cases, such as Collision Detection and determination of the size, it is very useful to use the ball.
Solution
You can access the sphere surrounded by each modelmesh in the model. By using the createmerged method, you can combine the ball to obtain the ball surrounded by the entire model.
However, because the sphere of each modelmesh is defined relative to the bone matrix, You need to convert it.
Working Principle
You will create a method to load a clip to a model variable, initialize its bone matrix array, and save the global sphere to the tag attribute of the model.
TIPS:You can use the tag attribute of the model to store any object. In this example, you use the tag attribute to store the ball. Tag attributes are frequently used in this chapter.
Private model loadmodelwithboundingsphere (ref matrix [] modeltransforms, string asset, contentmanager content) {model newmodel = content. load <model> (asset); modeltransforms = new matrix [newmodel. bones. count]; newmodel. copyabsolutebonetransformsto (modeltransforms); Return newmodel ;}
This method loads a model, which has been explained in tutorial 4-1. Before returning to a model, you need to traverse the model to view the sphere of the model (these balls are created by the default model processor during compilation, as shown in the explanation in tutorial 4-13 ).
Foreach (modelmesh mesh in newmodel. Meshes) {boundingsphere origmeshsphere = mesh. boundingsphere ;}
You want to combine these balls to obtain the global sphere of the entire model. You can achieve this by saving a new ball and combining these small balls.
Boundingsphere condition = new boundingsphere (); foreach (modelmesh mesh in newmodel. Meshes) {boundingsphere origmeshsphere = mesh. boundingsphere; condition = boundingsphere. createmerged (condition, origmeshsphere );}
In this way, completeboundingsphere is a big ball containing all the balls.
However, when you obtain the sphere of the modelmesh, the sphere is defined in the local space of the modelmesh. For example, a person's torso is surrounded by a ball of 80 cm, while the header is surrounded by only 30 cm. If you simply combine the two, you get 80cm of the ball, this is because the ball is completely contained in the ball.
To correctly combine the two, you must first move the ball in the header to the top of the trunk and then combine the two to get a large ball in the face.
In xNa, this means that you must first use the bone matrix contained in modelmesh to convert the sphere of the modelmesh, just like the followingCodeAs shown in:
Boundingsphere completeboundingsphere = new boundingsphere (); foreach (modelmesh mesh in newmodel. meshes) {boundingsphere origmeshsphere = mesh. boundingsphere; boundingsphere transmeshsphere = xnautils. transformboundingsphere (origmeshsphere, modeltransforms [mesh. parentbone. index]); completeboundingsphere = boundingsphere. createmerged (completeboundingsphere, transmeshsphere);} newmodel. tag = completeboundingsphere;
The correct global ball will be stored in the tag attribute of the model.
Note:The boundingsphere. Transform Method comes with the xNa framework, but it cannot process a matrix containing rotation. Therefore, I have included an extension version in the xnautils file. You can find this method in the example.
Usage
When you want to obtain a global box from the tag attribute, You need to first convert it to a boundingsphere object, because the tag attribute can store any type of objects:
Boundingsphere bsphere = (boundingsphere) mymodel. Tag;
Code
The following is the complete code, including initializing a model and storing its box in the tag attribute:
private model loadmodelwithboundingsphere (ref matrix [] modeltransforms, string asset, contentmanager content) {model newmodel = content. load
(asset); modeltransforms = new matrix [newmodel. bones. count]; newmodel. copyabsolutebonetransformsto (modeltransforms); boundingsphere completeboundingsphere = new boundingsphere (); foreach (modelmesh mesh in newmodel. meshes) {boundingsphere origmeshsphere = mesh. boundingsphere; boundingsphere transmeshsphere = xnautils. transformboundingsphere (origmeshsphere, modeltransforms [mesh. parentbone. index]); completeboundingsphere = boundingsphere. createmerged (completeboundingsphere, transmeshsphere);} newmodel. tag = completeboundingsphere; return newmodel ;}