void TSShapeLoader::computeBounds(Box3F& bounds) { // Compute the box that encloses the model geometry bounds = Box3F::Invalid; // Use bounds node geometry if present if ( boundsNode && boundsNode->getNumMesh() ) { for (S32 iMesh = 0; iMesh < boundsNode->getNumMesh(); iMesh++) { AppMesh* mesh = boundsNode->getMesh( iMesh ); if ( !mesh ) continue; Box3F meshBounds; mesh->computeBounds( meshBounds ); if ( meshBounds.isValidBox() ) bounds.intersect( meshBounds ); } } else { // Compute bounds based on all geometry in the model for (S32 iMesh = 0; iMesh < appMeshes.size(); iMesh++) { AppMesh* mesh = appMeshes[iMesh]; if ( !mesh ) continue; Box3F meshBounds; mesh->computeBounds( meshBounds ); if ( meshBounds.isValidBox() ) bounds.intersect( meshBounds ); } } }
void ColladaShapeLoader::computeBounds(Box3F& bounds) { TSShapeLoader::computeBounds(bounds); // Check if the model origin needs adjusting if ( bounds.isValidBox() && (ColladaUtils::getOptions().adjustCenter || ColladaUtils::getOptions().adjustFloor) ) { // Compute shape offset Point3F shapeOffset = Point3F::Zero; if ( ColladaUtils::getOptions().adjustCenter ) { bounds.getCenter( &shapeOffset ); shapeOffset = -shapeOffset; } if ( ColladaUtils::getOptions().adjustFloor ) shapeOffset.z = -bounds.minExtents.z; // Adjust bounds bounds.minExtents += shapeOffset; bounds.maxExtents += shapeOffset; // Now adjust all positions for root level nodes (nodes with no parent) for (S32 iNode = 0; iNode < shape->nodes.size(); iNode++) { if ( !appNodes[iNode]->isParentRoot() ) continue; // Adjust default translation shape->defaultTranslations[iNode] += shapeOffset; // Adjust animated translations for (S32 iSeq = 0; iSeq < shape->sequences.size(); iSeq++) { const TSShape::Sequence& seq = shape->sequences[iSeq]; if ( seq.translationMatters.test(iNode) ) { for (S32 iFrame = 0; iFrame < seq.numKeyframes; iFrame++) { S32 index = seq.baseTranslation + seq.translationMatters.count(iNode)*seq.numKeyframes + iFrame; shape->nodeTranslations[index] += shapeOffset; } } } } } }
bool EditTSCtrl::processCameraQuery(CameraQuery * query) { if(mDisplayType == DisplayTypePerspective) { query->ortho = false; } else { query->ortho = true; } if (getCameraTransform(&query->cameraMatrix)) { query->farPlane = gClientSceneGraph->getVisibleDistance() * smVisibleDistanceScale; query->nearPlane = gClientSceneGraph->getNearClip(); query->fov = mDegToRad(smCamFOV); if(query->ortho) { MatrixF camRot(true); const F32 camBuffer = 1.0f; Point3F camPos = query->cameraMatrix.getPosition(); F32 isocamplanedist = 0.0f; if(mDisplayType == DisplayTypeIsometric) { const RectI& vp = GFX->getViewport(); isocamplanedist = 0.25 * vp.extent.y * mSin(mIsoCamAngle); } // Calculate the scene bounds Box3F sceneBounds; computeSceneBounds(sceneBounds); if(!sceneBounds.isValidBox()) { sceneBounds.maxExtents = camPos + smMinSceneBounds; sceneBounds.minExtents = camPos - smMinSceneBounds; } else { query->farPlane = getMax(smMinSceneBounds.x * 2.0f, (sceneBounds.maxExtents - sceneBounds.minExtents).len() + camBuffer * 2.0f + isocamplanedist); } mRawCamPos = camPos; camPos += mOrthoCamTrans; switch(mDisplayType) { case DisplayTypeTop: camRot.setColumn(0, Point3F(1.0, 0.0, 0.0)); camRot.setColumn(1, Point3F(0.0, 0.0, -1.0)); camRot.setColumn(2, Point3F(0.0, 1.0, 0.0)); camPos.z = getMax(camPos.z + smMinSceneBounds.z, sceneBounds.maxExtents.z + camBuffer); break; case DisplayTypeBottom: camRot.setColumn(0, Point3F(1.0, 0.0, 0.0)); camRot.setColumn(1, Point3F(0.0, 0.0, 1.0)); camRot.setColumn(2, Point3F(0.0, -1.0, 0.0)); camPos.z = getMin(camPos.z - smMinSceneBounds.z, sceneBounds.minExtents.z - camBuffer); break; case DisplayTypeFront: camRot.setColumn(0, Point3F(-1.0, 0.0, 0.0)); camRot.setColumn(1, Point3F( 0.0, -1.0, 0.0)); camRot.setColumn(2, Point3F( 0.0, 0.0, 1.0)); camPos.y = getMax(camPos.y + smMinSceneBounds.y, sceneBounds.maxExtents.y + camBuffer); break; case DisplayTypeBack: camRot.setColumn(0, Point3F(1.0, 0.0, 0.0)); camRot.setColumn(1, Point3F(0.0, 1.0, 0.0)); camRot.setColumn(2, Point3F(0.0, 0.0, 1.0)); camPos.y = getMin(camPos.y - smMinSceneBounds.y, sceneBounds.minExtents.y - camBuffer); break; case DisplayTypeLeft: camRot.setColumn(0, Point3F( 0.0, -1.0, 0.0)); camRot.setColumn(1, Point3F( 1.0, 0.0, 0.0)); camRot.setColumn(2, Point3F( 0.0, 0.0, 1.0)); camPos.x = getMin(camPos.x - smMinSceneBounds.x, sceneBounds.minExtents.x - camBuffer); break; case DisplayTypeRight: camRot.setColumn(0, Point3F( 0.0, 1.0, 0.0)); camRot.setColumn(1, Point3F(-1.0, 0.0, 0.0)); camRot.setColumn(2, Point3F( 0.0, 0.0, 1.0)); camPos.x = getMax(camPos.x + smMinSceneBounds.x, sceneBounds.maxExtents.x + camBuffer); break; case DisplayTypeIsometric: camPos.z = sceneBounds.maxExtents.z + camBuffer + isocamplanedist; MatrixF angle(EulerF(mIsoCamAngle, 0, 0)); MatrixF rot(mIsoCamRot); camRot.mul(rot, angle); break; } query->cameraMatrix = camRot; query->cameraMatrix.setPosition(camPos); query->fov = mOrthoFOV; } smCamMatrix = query->cameraMatrix; smCamMatrix.getColumn(3,&smCamPos); smCamOrtho = query->ortho; smCamNearPlane = query->nearPlane; return true; } return false; }