zoukankan      html  css  js  c++  java
  • 处理模型——缩放模型

    问题

    当从磁盘载入模型时,往往会太大或太小,你想将模型缩放到定义的大小。

    解决方案

    首先你需要定义一个模型的全局包围球,前面一个教程已经解释了。知道了这个包围球,你就可以知道模型的当前尺寸了。从这个尺寸,你可以知道需要将模型放大或所小多少。你也可以将这个缩放操作储存在root Bone矩阵中,这样缩放会施加到模型中所有Bone的所有矩阵上(可见教程4-9)。

    工作原理

    通常,你使用的模型是由不同的工具制作的,或从网上下载的,你无法指定模型的大小。所以,如果你能将模型缩放到你想要的大小那会很棒。

    下面的代码计算模型需要缩放到多少,这需要存储在模型Tag属性中的全局包围球(见前一个教程)。

    private Matrix[] AutoScale(Model model, float requestedSize) 
    {
        BoundingSphere bSphere = (BoundingSphere)model.Tag; 
        
        float originalSize = bSphere.Radius * 2; 
        float scalingFactor = requestedSize / originalSize; 
        model.Root.Transform = model.Root.Transform * Matrix.CreateScale(scalingFactor); 
        Matrix[] modelTransforms = new Matrix[model.Bones.Count]; 
        model.CopyAbsoluteBoneTransformsTo(modelTransforms); 
        
        return modelTransforms; 
    } 

    你需要将模型传递给这个方法指定最终的模型有多大。这个方法一开始获取一个模型的全局包围球,你需要将求的半径乘2获取球的大小,对应于模型的初始大小。接下来,你将requestedSize除以这个值获取这个模型需要缩放到多大。你可以使用这个缩放因子创建一个矩阵,将这个矩阵作为绘制模型时的世界矩阵,这样你的模型就会缩放到想要的大小了。

    在Root Bone上施加缩放

    构建良好的模型将所有子网格链接到它们的root bone。这意味着当你缩放了root bone矩阵 (见教程4-9),所有ModelMeshes也会自动缩放。你可以通过将Root矩阵乘以缩放矩阵实现,在前面计算的scalingFactor基础上,将这个结果矩阵存储在模型中。因为你改变了Bone矩阵的内容,所以你必须提取modelTransforms矩阵的新版本。

    注意:更好的方法是在自定义模型处理器中使用一个可以进行配置的变量,见教程4-12学习如何扩展默认模型处理器。

    代码

    在LoadContent方法中,你需要使用两行代码加载并缩放模型:

    myModel = XNAUtils.LoadModelWithBoundingSphere(ref modelTransforms, "tank", Content); 
    modelTransforms = AutoScale(myModel, 10.0f); 

    当绘制模型时,你可以使用普通的代码,因为缩放信息已经被储存在模型的Root bone中了。通过这种方式,每次当你调用Model. CopyAbsoluteBoneTransformsTo方法时,所有的结果矩阵都已经包含了缩放操作,这样在将模型的各个部分绘制到屏幕之前它们已经进行了缩放。

    Matrix worldMatrix = Matrix.Identity; 
    myModel.CopyAbsoluteBoneTransformsTo(modelTransforms); 
    foreach (ModelMesh mesh in myModel.Meshes) 
    {
        foreach (BasicEffect effect in mesh.Effects) 
        { 
            effect.EnableDefaultLighting(); 
            effect.World = modelTransforms[mesh.ParentBone.Index] * worldMatrix; 
            effect.View = fpsCam.ViewMatrix; 
            effect.Projection = fpsCam.ProjectionMatrix; 
        }
        mesh.Draw(); 
    } 
  • 相关阅读:
    ABB机器人 带参数例行程序
    面试题10- I:斐波那契数列(C++)
    面试题39:数组中出现次数超过一半的数字(C++)
    面试题50:第一个只出现一次的字符(C++)
    第八部分 表的基本操作
    第七部分 表中数据的基本操作
    面试题18:删除链表的节点(C++)
    面试题35:复杂链表的复制(C++)
    面试题54:二叉搜索树的第k大节点(C++)
    面试题62:圆圈中最后剩下的数字(C++)
  • 原文地址:https://www.cnblogs.com/AlexCheng/p/2120139.html
Copyright © 2011-2022 走看看