void SurfaceVectorJump<EvalT, Traits>::evaluateFields( typename Traits::EvalData workset) { Intrepid2::Vector<ScalarT> vecA(0, 0, 0), vecB(0, 0, 0), vecJump(0, 0, 0); for (int cell = 0; cell < workset.numCells; ++cell) { for (int pt = 0; pt < num_qps_; ++pt) { vecA.fill(Intrepid2::ZEROS); vecB.fill(Intrepid2::ZEROS); for (int node = 0; node < num_plane_nodes_; ++node) { int topNode = node + num_plane_nodes_; vecA += Intrepid2::Vector<ScalarT>( ref_values_(node, pt) * vector_(cell, node, 0), ref_values_(node, pt) * vector_(cell, node, 1), ref_values_(node, pt) * vector_(cell, node, 2)); vecB += Intrepid2::Vector<ScalarT>( ref_values_(node, pt) * vector_(cell, topNode, 0), ref_values_(node, pt) * vector_(cell, topNode, 1), ref_values_(node, pt) * vector_(cell, topNode, 2)); } vecJump = vecB - vecA; jump_(cell, pt, 0) = vecJump(0); jump_(cell, pt, 1) = vecJump(1); jump_(cell, pt, 2) = vecJump(2); } } }
const std::vector<T>& vec() const { if (m_A) return vecA(); else if (m_B) return vecB(); else return vecC(); }
TEST(VectorTest, DotTest) { Math::Vector vecA(0.8202190530968309, 0.0130926060162780, 0.2411914183883510); Math::Vector vecB(-0.0524083951404069, 1.5564932716738220, -0.8971342631500536); float expectedDot = -0.238988896477326; EXPECT_TRUE(Math::IsEqual(Math::DotProduct(vecA, vecB), expectedDot, TEST_TOLERANCE)); }
// Returns cross product between two 3D vectors Point Bezier::crossP(Point a, Point b) { float* valueA = a.getValues(); float* valueB = b.getValues(); Eigen::Vector3f vecA(valueA[0], valueA[1], valueA[2]); Eigen::Vector3f vecB(valueB[0], valueB[1], valueB[2]); Eigen::Vector3f result = vecA.cross(vecB); Point point(result[0], result[1], result[2]); return point; }
TEST(VectorTest, CrossTest) { Math::Vector vecA(1.37380499798567, 1.18054518384682, 1.95166361293121); Math::Vector vecB(0.891657855926886, 0.447591335394532, -0.901604070087823); Math::Vector expectedCross(-1.937932065431669, 2.978844370287636, -0.437739173833581); Math::Vector expectedReverseCross = -expectedCross; EXPECT_TRUE(Math::VectorsEqual(vecA.CrossMultiply(vecB), expectedCross, TEST_TOLERANCE)); EXPECT_TRUE(Math::VectorsEqual(vecB.CrossMultiply(vecA), expectedReverseCross, TEST_TOLERANCE)); }
/** * Calculates bounds for a CqCurve. * * NOTE: This method makes the same assumptions as * CqSurfacePatchBicubic::Bound() does about the convex-hull property of the * curve. This is fine most of the time, but the user can specify basis * matrices like Catmull-Rom, which are non-convex. * * FIXME: Make sure that all hulls which reach this method are convex! * * @return CqBound object containing the bounds. */ void CqCurve::Bound(CqBound* bound) const { // Get the boundary in camera space. CqVector3D vecA( FLT_MAX, FLT_MAX, FLT_MAX ); CqVector3D vecB( -FLT_MAX, -FLT_MAX, -FLT_MAX ); TqFloat maxCameraSpaceWidth = 0; TqUint nWidthParams = cVarying(); for ( TqUint i = 0; i < ( *P() ).Size(); i++ ) { // expand the boundary if necessary to accomodate the // current vertex CqVector3D vecV = vectorCast<CqVector3D>(P()->pValue( i )[0]); if ( vecV.x() < vecA.x() ) vecA.x( vecV.x() ); if ( vecV.y() < vecA.y() ) vecA.y( vecV.y() ); if ( vecV.x() > vecB.x() ) vecB.x( vecV.x() ); if ( vecV.y() > vecB.y() ) vecB.y( vecV.y() ); if ( vecV.z() < vecA.z() ) vecA.z( vecV.z() ); if ( vecV.z() > vecB.z() ) vecB.z( vecV.z() ); // increase the maximum camera space width of the curve if // necessary if ( i < nWidthParams ) { TqFloat camSpaceWidth = width()->pValue( i )[0]; if ( camSpaceWidth > maxCameraSpaceWidth ) { maxCameraSpaceWidth = camSpaceWidth; } } } // increase the size of the boundary by half the width of the // curve in camera space vecA -= ( maxCameraSpaceWidth / 2.0 ); vecB += ( maxCameraSpaceWidth / 2.0 ); bound->vecMin() = vecA; bound->vecMax() = vecB; AdjustBoundForTransformationMotion( bound ); }
// // Deform computation // MStatus jhMeshBlur::deform( MDataBlock& block,MItGeometry& iter,const MMatrix& m,unsigned int multiIndex) { MStatus returnStatus; // Envelope float envData = block.inputValue(envelope, &returnStatus).asFloat(); CHECK_MSTATUS(returnStatus); if(envData == 0) return MS::kFailure; /* VARIABLES */ //float factor = block.inputValue(aShapeFactor, &returnStatus).asFloat(); float fStrength = block.inputValue(aStrength, &returnStatus).asFloat(); CHECK_MSTATUS(returnStatus); if (fStrength == 0) return MS::kFailure; float fThreshold = block.inputValue(aTreshhold, &returnStatus).asFloat(); CHECK_MSTATUS(returnStatus); float fW = 0.0f; // weight float fDistance; fStrength *= envData; double dKracht = block.inputValue(aInterpPower, &returnStatus).asDouble(); CHECK_MSTATUS(returnStatus); double dDotProduct; // Dotproduct of the point bool bTweakblur = block.inputValue(aTweakBlur, &returnStatus).asBool(); CHECK_MSTATUS(returnStatus); bool bQuad = block.inputValue(aQuadInterp, &returnStatus).asBool(); CHECK_MSTATUS(returnStatus); MTime inTime = block.inputValue(aTime).asTime(); int nTijd = (int)inTime.as(MTime::kFilm); MFloatVectorArray currentNormals; // normals of mesh MFnPointArrayData fnPoints; // help converting to MPointArrays MFloatVector dirVector; // direction vector of the point MFloatVector normal; // normal of the point MPointArray savedPoints; // save all point before edited MMatrix matInv = m.inverse(); // inversed matrix MPoint ptA; // current point (iter mesh) MPoint ptB; // previous point (iter mesh) MPoint ptC; // mesh before previous point (iter mesh) // get node, use node to get inputGeom, use inputGeom to get mesh data, use mesh data to get normal data MFnDependencyNode nodeFn(this->thisMObject()); MPlug inGeomPlug(nodeFn.findPlug(this->inputGeom,true)); MObject inputObject(inGeomPlug.asMObject()); MFnMesh inMesh(inputObject); inMesh.getVertexNormals(true, currentNormals); // get the previous mesh data MPlug oldMeshPlug = nodeFn.findPlug(MString("oldMesh")); MPlug oldMeshPositionsAPlug = oldMeshPlug.elementByLogicalIndex((multiIndex*4) + 0); MPlug oldMeshPositionsBPlug = oldMeshPlug.elementByLogicalIndex((multiIndex*4) + 1); MPlug oldMeshPositionsCPlug = oldMeshPlug.elementByLogicalIndex((multiIndex*4) + 2); // cache for tweak mode MPlug oldMeshPositionsDPlug = oldMeshPlug.elementByLogicalIndex((multiIndex*4) + 3); // cache for tweak mode // convert to MPointArrays MObject objOldMeshA; MObject objOldMeshB; MObject objOldMeshC; // cache MObject objOldMeshD; // cache oldMeshPositionsAPlug.getValue(objOldMeshA); oldMeshPositionsBPlug.getValue(objOldMeshB); oldMeshPositionsCPlug.getValue(objOldMeshC); // cache oldMeshPositionsDPlug.getValue(objOldMeshD); // cache fnPoints.setObject(objOldMeshA); MPointArray oldMeshPositionsA = fnPoints.array(); fnPoints.setObject(objOldMeshB); MPointArray oldMeshPositionsB = fnPoints.array(); fnPoints.setObject(objOldMeshC); MPointArray oldMeshPositionsC = fnPoints.array(); // cache fnPoints.setObject(objOldMeshD); MPointArray oldMeshPositionsD = fnPoints.array(); // cache // If mesh position variables are empty,fill them with default values if(oldMeshPositionsA.length() == 0 || nTijd <= 1){ iter.allPositions(oldMeshPositionsA); for(int i=0; i < oldMeshPositionsA.length(); i++) { // convert to world oldMeshPositionsA[i] = oldMeshPositionsA[i] * m; } oldMeshPositionsB.copy(oldMeshPositionsA); oldMeshPositionsC.copy(oldMeshPositionsA); // cache oldMeshPositionsD.copy(oldMeshPositionsA); // cache } // get back old date again if (bTweakblur == true) { // restore cache oldMeshPositionsA.copy(oldMeshPositionsC); oldMeshPositionsB.copy(oldMeshPositionsD); } iter.allPositions(savedPoints); for(int i=0; i < savedPoints.length(); i++) { // convert points to world points savedPoints[i] = savedPoints[i] * m; } // Actual Iteration through points for (; !iter.isDone(); iter.next()){ // get current position ptA = iter.position(); // get old positions ptB = oldMeshPositionsA[iter.index()] * matInv; ptC = oldMeshPositionsB[iter.index()] * matInv; fDistance = ptA.distanceTo(ptB); fW = weightValue(block,multiIndex,iter.index()); if (fDistance * (fStrength*fW) < fThreshold && fThreshold > 0){ iter.setPosition(ptA); } else { // aim/direction vector to calculate strength dirVector = (ptA - ptB); // (per punt) dirVector.normalize(); normal = currentNormals[iter.index()]; dDotProduct = normal.x * dirVector.x + normal.y * dirVector.y + normal.z * dirVector.z; if(bQuad == true){ MVector vecA(((ptB - ptC) + (ptA - ptB)) / 2); vecA.normalize(); MPoint hiddenPt(ptB + (vecA * fDistance) * dKracht); ptA = quadInterpBetween(ptB, hiddenPt, ptA, (1 - fStrength * fW) + (linearInterp(dDotProduct, -1, 1) * (fStrength * fW) ) ); } else { MPoint halfway = (ptA - ptB) * 0.5; MPoint offset = halfway * dDotProduct * (fStrength*fW); ptA = ptA - ((halfway * (fStrength*fW)) - offset); // + (offset * strength); } // set new value iter.setPosition(ptA); } } if(bTweakblur == false){ oldMeshPositionsD.copy(oldMeshPositionsB); oldMeshPositionsC.copy(oldMeshPositionsA); oldMeshPositionsB.copy(oldMeshPositionsA); oldMeshPositionsA.copy(savedPoints); // Save back to plugs objOldMeshA = fnPoints.create(oldMeshPositionsA); objOldMeshB = fnPoints.create(oldMeshPositionsB); objOldMeshC = fnPoints.create(oldMeshPositionsC); objOldMeshD = fnPoints.create(oldMeshPositionsD); oldMeshPositionsAPlug.setValue(objOldMeshA); oldMeshPositionsBPlug.setValue(objOldMeshB); oldMeshPositionsCPlug.setValue(objOldMeshC); oldMeshPositionsDPlug.setValue(objOldMeshD); } return returnStatus; }
void SceneManager::Update() { RenderLayerManager & renderManager = RenderLayerManager::GetRenderLayerManager(); const PVRTVec3 center = renderManager.GetCenter(); float occlusionRadius = renderManager.GetOcclusionRadius(); PVRTVec4 vecA( mLookMtx->f[12], 0.0f, mLookMtx->f[14], 1); PVRTVec4 vecB( GLOBAL_SCALE * FRUSTUM_W, 0.0f, GLOBAL_SCALE * FRUSTUM_D, 1); PVRTVec4 vecC( GLOBAL_SCALE * -FRUSTUM_W, 0.0f, GLOBAL_SCALE * FRUSTUM_D, 1); vecB = *mLookMtx * vecB; vecC = *mLookMtx * vecC; PVRTVec2 A(vecA.x, vecA.z); PVRTVec2 B(vecB.x, vecB.z); PVRTVec2 C(vecC.x, vecC.z); mToApplyCount = 0; if (mQuadTree) { static QuadNode * quadNodes[256]={0}; int quadNodeCount = 0; //mQuadTree->GetQuads(center.x, center.z, occlusionRadius, quadNodes, quadNodeCount); mQuadTree->GetQuadsCameraFrustum(quadNodes, quadNodeCount, mLookMtx); quadNodeCount--; bool useFrustumCulling = true; //!!!!!!!!!!!!!!!!!!!!! for (int quad = quadNodeCount ; quad >=0 ; quad--) { QuadNode * pQuadNode = quadNodes[quad]; List & dataList = pQuadNode->GetDataList(); ListIterator listIter(dataList); while( Node * pRootNode = (Node*)listIter.GetPtr() ) { if (!pRootNode->IsVisible()) continue; //pRootNode->UpdateWithoutChildren(); bool useOcclusionRadius = pRootNode->GetUseOcclusionCulling(); PVRTVec3 worldPos = pRootNode->GetWorldTranslation(); if (!useFrustumCulling && useOcclusionRadius) { PVRTVec3 distVec = worldPos - center; if ( distVec.lenSqr() < MM(occlusionRadius) ) { pRootNode->SetInFrustum(true); pRootNode->Update(); mToApply[mToApplyCount] = pRootNode; mToApplyCount++; } else { pRootNode->SetInFrustum(false); } } else if (useFrustumCulling) { PVRTVec2 P(worldPos.x, worldPos.z); PVRTVec2 v0 = C - A; PVRTVec2 v1 = B - A; PVRTVec2 v2 = P - A; // Compute dot products float dot00 = v0.dot(v0); float dot01 = v0.dot(v1); float dot02 = v0.dot(v2); float dot11 = v1.dot(v1); float dot12 = v1.dot(v2); // Compute barycentric coordinates float invDenom = 1.0f / (dot00 * dot11 - dot01 * dot01); float u = (dot11 * dot02 - dot01 * dot12) * invDenom; float v = (dot00 * dot12 - dot01 * dot02) * invDenom; bool addToList = false; // Check if point is in triangle //PVRTVec3 distVec = worldPos - center; //if ( distVec.lenSqr() < MM(occlusionRadius) ) { if ( (u > 0) && (v > 0) && (u + v < 1)) { addToList = true; } else if ( Collision::CircleTriangleEdgeIntersection(A,B,P, pRootNode->GetRadius() ) ) { addToList = true; } else if ( Collision::CircleTriangleEdgeIntersection(A,C,P, pRootNode->GetRadius() )) { addToList = true; } if (addToList) { pRootNode->SetInFrustum(true); //pRootNode->Update(); mToApply[mToApplyCount] = pRootNode; mToApplyCount++; } else { pRootNode->SetInFrustum(false); } } //else //{ // pRootNode->SetInFrustum(false); //} } else { pRootNode->SetInFrustum(true); //pRootNode->Update(); mToApply[mToApplyCount] = pRootNode; mToApplyCount++; } } } } for (int n=0;n<mNodeCount;n++) { Node * pRootNode = mRootNodes[n]; if (!pRootNode->IsVisible()) continue; pRootNode->UpdateWithoutChildren(); bool useOcclusionRadius = pRootNode->GetUseOcclusionCulling(); PVRTVec3 worldPos = pRootNode->GetWorldTranslation(); PVRTVec3 distVec = worldPos - center; if (useOcclusionRadius) { if ( distVec.lenSqr() < MM(occlusionRadius) ) { PVRTVec2 P(worldPos.x, worldPos.z); PVRTVec2 v0 = C - A; PVRTVec2 v1 = B - A; PVRTVec2 v2 = P - A; // Compute dot products float dot00 = v0.dot(v0); float dot01 = v0.dot(v1); float dot02 = v0.dot(v2); float dot11 = v1.dot(v1); float dot12 = v1.dot(v2); // Compute barycentric coordinates float invDenom = 1.0f / (dot00 * dot11 - dot01 * dot01); float u = (dot11 * dot02 - dot01 * dot12) * invDenom; float v = (dot00 * dot12 - dot01 * dot02) * invDenom; bool addToList = false; // Check if point is in triangle //PVRTVec3 distVec = worldPos - center; //if ( distVec.lenSqr() < MM(occlusionRadius) ) { if ( (u > 0) && (v > 0) && (u + v < 1)) { addToList = true; } else if ( Collision::CircleTriangleEdgeIntersection(A,B,P, pRootNode->GetRadius() ) ) { addToList = true; } else if ( Collision::CircleTriangleEdgeIntersection(A,C,P, pRootNode->GetRadius() )) { addToList = true; } if (addToList) { pRootNode->SetInFrustum(true); pRootNode->Update(); mToApply[mToApplyCount] = pRootNode; mToApplyCount++; } else { pRootNode->SetInFrustum(false); } } /* pRootNode->SetInFrustum(true); pRootNode->Update(); mToApply[mToApplyCount] = pRootNode; mToApplyCount++; */ } else { pRootNode->SetInFrustum(false); } } else { pRootNode->SetInFrustum(true); pRootNode->Update(); mToApply[mToApplyCount] = pRootNode; mToApplyCount++; } /* PVRTVec3 worldPos = pRootNode->GetWorldTranslation(); PVRTVec3 distVec = worldPos - center; if (!pRootNode->GetUseOcclusionCulling()) { pRootNode->SetInFrustum(true); } else if ( distVec.lenSqr() < occlusionRadius ) { pRootNode->SetInFrustum(true); } else { pRootNode->SetInFrustum(false); } */ } }