////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// * Builds a collision model. * \param create [in] model creation structure * \return true if success */ ////////////////////////////////////////////////////////////////////////////////////////////////
| 138 | */ |
| 139 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
| 140 | bool Model::Build(const OPCODECREATE& create) |
| 141 | { |
| 142 | // 1) Checkings |
| 143 | if(!create.mIMesh || !create.mIMesh->IsValid()) return false; |
| 144 | |
| 145 | // For this model, we only support complete trees |
| 146 | if(create.mSettings.mLimit!=1) return SetIceError("OPCODE WARNING: supports complete trees only! Use mLimit = 1.\n", null); |
| 147 | |
| 148 | // Look for degenerate faces. |
| 149 | udword NbDegenerate = create.mIMesh->CheckTopology(); |
| 150 | if(NbDegenerate) Log(_F("OPCODE WARNING: found %d degenerate faces in model! Collision might report wrong results!\n", NbDegenerate)); |
| 151 | // We continue nonetheless.... |
| 152 | |
| 153 | Release(); // Make sure previous tree has been discarded [Opcode 1.3, thanks Adam] |
| 154 | |
| 155 | // 1-1) Setup mesh interface automatically [Opcode 1.3] |
| 156 | SetMeshInterface(create.mIMesh); |
| 157 | |
| 158 | // Special case for 1-triangle meshes [Opcode 1.3] |
| 159 | udword NbTris = create.mIMesh->GetNbTriangles(); |
| 160 | if(NbTris==1) |
| 161 | { |
| 162 | // We don't need to actually create a tree here, since we'll only have a single triangle to deal with anyway. |
| 163 | // It's a waste to use a "model" for this but at least it will work. |
| 164 | mModelCode |= OPC_SINGLE_NODE; |
| 165 | return true; |
| 166 | } |
| 167 | |
| 168 | // 2) Build a generic AABB Tree. |
| 169 | mSource = ICE_NEW(AABBTree); |
| 170 | CHECKALLOC(mSource); |
| 171 | |
| 172 | // 2-1) Setup a builder. Our primitives here are triangles from input mesh, |
| 173 | // so we use an AABBTreeOfTrianglesBuilder..... |
| 174 | { |
| 175 | AABBTreeOfTrianglesBuilder TB; |
| 176 | TB.mIMesh = create.mIMesh; |
| 177 | TB.mSettings = create.mSettings; |
| 178 | TB.mNbPrimitives = NbTris; |
| 179 | if(!mSource->Build(&TB)) return false; |
| 180 | } |
| 181 | |
| 182 | // 3) Create an optimized tree according to user-settings |
| 183 | if(!CreateTree(create.mNoLeaf, create.mQuantized)) return false; |
| 184 | |
| 185 | // 3-2) Create optimized tree |
| 186 | if(!mTree->Build(mSource)) return false; |
| 187 | |
| 188 | // 3-3) Delete generic tree if needed |
| 189 | if(!create.mKeepOriginal) DELETESINGLE(mSource); |
| 190 | |
| 191 | #ifdef __MESHMERIZER_H__ |
| 192 | // 4) Convex hull |
| 193 | if(create.mCollisionHull) |
| 194 | { |
| 195 | // Create hull |
| 196 | mHull = new CollisionHull; |
| 197 | CHECKALLOC(mHull); |
no test coverage detected