void RasNormalMap::DoPerVertexLighting( VertexBuffer& workingVB, FaceList& workingFaces, RenderObject& obj ) { const VEC3& camPos = g_env.renderer->m_camera.GetPos().GetVec3(); MAT44 matInvWorld = obj.m_matWorld.Inverse(); for (size_t iVert=0; iVert<obj.m_verts.size(); ++iVert) { SVertex& vert = obj.m_verts[iVert]; // Get the matrix which transforms vector from object space to tangent space MAT44 matTBN; matTBN.SetRow(0, VEC4(vert.tangent, 0)); matTBN.SetRow(1, VEC4(vert.binormal, 0)); matTBN.SetRow(2, VEC4(vert.normal, 0)); // Calc light dir in object space const VEC3& lightDir = g_env.renderer->m_testLight.neg_dir; vert.lightDirTS = Common::Transform_Vec3_By_Mat44(lightDir, matInvWorld, false).GetVec3(); // Transform! vert.lightDirTS = Common::Transform_Vec3_By_Mat44(vert.lightDirTS, matTBN, false).GetVec3(); // Half-angle vector VEC3 eyeDir = Common::Sub_Vec3_By_Vec3(camPos, vert.pos.GetVec3()); eyeDir.Normalize(); Common::Add_Vec3_By_Vec3(vert.halfAngleTS, eyeDir, lightDir); vert.halfAngleTS.Normalize(); vert.halfAngleTS = Common::Transform_Vec3_By_Mat44(vert.halfAngleTS, matTBN, false).GetVec3(); } }
void CPlayerBase::UpdateCinematic(float elapsed) { static float time_out = 2.f; time_out -= getDeltaTime(); TCompTransform* player_transform = myEntity->get<TCompTransform>(); float yaw, pitch; transform->getAngles(&yaw, &pitch); float dist = simpleDistXZ(cc->GetPosition(), cinematicTargetPos); if (dist < epsilonPos || time_out <= 0.f) { if (time_out <= 0.f) cc->teleport(cinematicTargetPos); time_out = 2.f; // Reach position float deltaYaw = cinematicTargetYaw - yaw; if (abs(deltaYaw) < epsilonYaw) { //In position and Oriented onCinematic = false; logic_manager->throwUserEvent(cinematicEndCode); ChangeCommonState("idle"); } else { //Orientation to target transform->setAngles(yaw * 0.9f + 0.1f * cinematicTargetYaw, pitch); } } else { // Go to target float deltaYaw = transform->getDeltaYawToAimTo(cinematicTargetPos); if (deltaYaw > epsilonYaw) transform->setAngles(yaw + 0.1f * deltaYaw, pitch); VEC3 dir = cinematicTargetPos - cc->GetPosition(); dir.y = 0; dir.Normalize(); cc->AddMovement(dir, player_max_speed * getDeltaTime()); moving = true; ChangeCommonState("moving"); } }
bool interLineSeg(const VEC3& A, const VEC3& AB, typename VEC3::DATA_TYPE AB2, const VEC3& P, const VEC3& Q, VEC3& inter) { #define EPSILON (1.0e-5) typedef typename VEC3::DATA_TYPE T ; T dist = Geom::distancePoint2TrianglePlane(AB-A,A,P,Q); // std::cout << "dist "<< dist << std::endl; if (dist>EPSILON) return false; VEC3 AP = P - A ; VEC3 PQ = Q - P ; T X = AB * PQ ; T beta = ( AB2 * (AP*PQ) - X * (AP*AB) ) / ( X*X - AB2 * PQ.norm2() ) ; // std::cout << "beta "<< beta << std::endl; if ((beta<0.0) || (beta>1.0)) return false; inter = beta*Q +(1.0-beta)*P; return true; #undef EPSILON }
//------------------------------------------------------------------------------- void Renderer::Update(float dt) { static DWORD nFrameCnt = 0; static float fFrameTime = 0; // Calc FPS ++nFrameCnt; fFrameTime += dt; if (fFrameTime >= 1.0f) { g_env.pFrameStat->lastFPS = nFrameCnt / fFrameTime; nFrameCnt = 0; fFrameTime = 0; } // Update cBuffer m_cBufferGlobal.time = GetTickCount() / 1000.0f; Camera* cam = g_env.pSceneMgr->GetCamera(); const MAT44& matView = cam->GetViewMatrix(); const MAT44& matProj = cam->GetProjMatrix(); m_cBufferGlobal.camPos = cam->GetPos(); VEC3 vNegLight = g_env.pSceneMgr->GetSunLight().lightDir; vNegLight.Neg(); vNegLight.Normalize(); m_cBufferGlobal.lightDirection = vNegLight; m_cBufferGlobal.lightColor = g_env.pSceneMgr->GetSunLight().lightColor; m_cBufferGlobal.ambientColor.Set(0.2f, 0.2f, 0.2f); m_cBufferGlobal.nearZ = cam->GetNearClip(); m_cBufferGlobal.farZ = cam->GetFarClip(); m_cBufferGlobal.shadowMapTexelSize = 1.0f / g_env.pSceneMgr->GetShadowMapSize(); m_cBufferGlobal.frameBufferSize[0] = m_wndWidth; m_cBufferGlobal.frameBufferSize[1] = m_wndHeight; m_cBufferGlobal.frameBufferSize[2] = m_cBufferGlobal.frameBufferSize[3] = 0; cam->GetFarCorner(m_cBufferGlobal.frustumFarCorner); #if USE_PSSM ShadowMapPSSM* pPSSM = g_env.pSceneMgr->GetShadowMap()->GetPSSM(); m_cBufferGlobal.matShadow[0] = pPSSM->GetShadowTransform(0).Transpose(); m_cBufferGlobal.matShadow[1] = pPSSM->GetShadowTransform(1).Transpose(); m_cBufferGlobal.matShadow[2] = pPSSM->GetShadowTransform(2).Transpose(); #else m_cBufferGlobal.matShadow[0] = g_env.pSceneMgr->GetShadowMap()->GetShadowTransform().Transpose(); #endif m_cBufferGlobal.matView = matView.Transpose(); m_cBufferGlobal.matProj = matProj.Transpose(); m_cBufferGlobal.matInvView = matView.Inverse().Transpose(); m_cBufferGlobal.matViewProj = m_cBufferGlobal.matProj * m_cBufferGlobal.matView; UpdateGlobalCBuffer(true, true, true); }
IK_IMPL_SOLVER(grabPilaIK, info, result) { GET_COMP(mole_t, info.handle, TCompTransform); GET_COMP(skc, info.handle, SkelControllerMole); GET_COMP(pila_t, skc->getGrabbedPila(), TCompTransform); VEC3 right = -mole_t->getLeft(); right.Normalize(); result.new_pos = pila_t->getPosition() + right * 0.3f; //result.bone_normal = skc->getGrabNormalLeft(); }
/** * @brief computeLengthEdges * Demonstrate usage of 2 attributes on 2 differents orbits. * @param map the map * @param pos attribute handler of position of vertices * @param len attribute handler of length of edges */ void computeLengthEdges(MAP& map,const VertexAttribute<VEC3, MAP>& pos, EdgeAttribute<float, MAP> len) { // warning c++11 lambda syntax foreach_cell<EDGE>(map,[&](Edge e) // for all edge e of map do { VEC3 P1 = pos[e.dart]; // access with dart because of access to VertexAttribute with an edge VEC3 P2 = pos[map.phi1(e)]; // phi1 return a dart so no problem (and e can auto-cast in dart) VEC3 V = P2 - P1; len[e] = V.norm(); }); }
void SimpleGMap2::cb_initGL() { Utils::GLSLShader::setCurrentOGLVersion(1) ; Geom::BoundingBox<VEC3> bb = Algo::Geometry::computeBoundingBox<PFP>(myMap, position) ; VEC3 gPosObj = bb.center() ; float tailleX = bb.size(0) ; float tailleY = bb.size(1) ; float tailleZ = bb.size(2) ; float gWidthObj = std::max<float>(std::max<float>(tailleX, tailleY), tailleZ) ; setParamObject(gWidthObj, gPosObj.data()); }
//--------------------------------------------------------------------- void TerrainQuadTreeNode::mergeIntoBounds(long x, long y, const VEC3& pos) { if (pointIntersectsNode(x, y)) { VEC3 localPos = pos - mLocalCentre; mAABB.Merge(localPos); mBoundingRadius = std::max(mBoundingRadius, localPos.GetLength()); if (!isLeaf()) { for (int i = 0; i < 4; ++i) mChildren[i]->mergeIntoBounds(x, y, pos); } } }
void SimpleGMap3::cb_initGL() { Geom::BoundingBox<PFP::VEC3> bb = Algo::Geometry::computeBoundingBox<PFP>(myMap, position) ; VEC3 gPosObj = bb.center() ; float tailleX = bb.size(0) ; float tailleY = bb.size(1) ; float tailleZ = bb.size(2) ; float gWidthObj = std::max<float>(std::max<float>(tailleX, tailleY), tailleZ) ; setParamObject(gWidthObj, gPosObj.data()); m_render_topo = new Algo::Render::GL2::Topo3RenderGMap<PFP>(); m_render_topo->setDartWidth(2.0f); m_render_topo->setInitialDartsColor(1.0f,1.0f,1.0f); m_render_topo->updateData(myMap, position, 0.9f,0.9f,0.8f); }
void CPlayerBase::UpdateMoves() { PROFILE_FUNCTION("update moves base"); TCompTransform* player_transform = myEntity->get<TCompTransform>(); VEC3 player_position = player_transform->getPosition(); VEC3 direction = directionForward + directionLateral; CEntity * camera_e = camera; TCompTransform* camera_comp = camera_e->get<TCompTransform>(); direction.Normalize(); float yaw, pitch; camera_comp->getAngles(&yaw, &pitch); float new_x, new_z; new_x = direction.x * cosf(yaw) + direction.z*sinf(yaw); new_z = -direction.x * sinf(yaw) + direction.z*cosf(yaw); direction.x = new_x; direction.z = new_z; direction.Normalize(); float new_yaw = player_transform->getDeltaYawToAimDirection(direction); clampAbs_me(new_yaw, player_rotation_speed * getDeltaTime()); player_transform->getAngles(&yaw, &pitch); player_transform->setAngles(new_yaw + yaw, pitch); //Set current velocity with friction float drag = 2.5f*getDeltaTime(); float drag_i = (1 - drag); if (moving) player_curr_speed = drag_i*player_curr_speed + drag*player_max_speed; else player_curr_speed = drag_i*player_curr_speed - drag*player_max_speed; if (player_curr_speed < 0) { player_curr_speed = 0.0f; directionForward = directionLateral = VEC3(0, 0, 0); } cc->AddMovement(direction, player_curr_speed*getDeltaTime()); if (moving) UpdateMovingWithOther(); }
Intersection intersectionLineTriangle(const VEC3& P, const VEC3& Dir, const VEC3& Ta, const VEC3& Tb, const VEC3& Tc, VEC3& Inter) { typedef typename VEC3::DATA_TYPE T ; VEC3 u = Tb - Ta ; VEC3 v = Tc - Ta ; VEC3 n = u ^ v ; VEC3 w0 = P - Ta ; T a = -(n * w0) ; T b = (n * Dir) ; #define PRECISION 1e-20 if(fabs(b) < PRECISION) //ray parallel to triangle return NO_INTERSECTION ; #undef PRECISION T r = a / b ; Inter = P + r * Dir ; // intersect point of ray and plane // is I inside T? T uu = u.norm2() ; T uv = u * v ; T vv = v.norm2() ; VEC3 w = Inter - Ta ; T wu = w * u ; T wv = w * v ; T D = (uv * uv) - (uu * vv) ; // get and test parametric coords T s = ((uv * wv) - (vv * wu)) / D ; if(s < T(0) || s > T(1)) return NO_INTERSECTION ; T t = ((uv * wu) - (uu * wv)) / D ; if(t < T(0) || (s + t) > T(1)) return NO_INTERSECTION ; if((s == T(0) || s == T(1))) if(t == T(0) || t == T(1)) return VERTEX_INTERSECTION ; else return EDGE_INTERSECTION ; else if(t == T(0) || t == T(1)) return EDGE_INTERSECTION ; return FACE_INTERSECTION ; }
void CPlayerBase::renderInMenu() { PROFILE_FUNCTION("render in menu base"); VEC3 direction = directionForward + directionLateral + directionVertical; direction.Normalize(); direction = direction + directionJump; TCompTransform* player_transform = myEntity->get<TCompTransform>(); VEC3 player_position = player_transform->getPosition(); ImGui::Text("NODE: %s\n", state.c_str()); ImGui::Text("position: %.4f, %.4f, %.4f\n", player_position.x, player_position.y, player_position.z); ImGui::Text("direction: %.4f, %.4f, %.4f", direction.x, direction.y, direction.z); ImGui::Text("jump: %.5f", jspeed); ImGui::DragFloat("time_start_falling", &time_start_falling); ImGui::DragFloat("max_time_start_falling", &max_time_start_falling); }
bool intersectionSphereEdge(typename PFP::MAP& map, const typename PFP::VEC3& center, typename PFP::REAL radius, Edge e, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP>& position, typename PFP::REAL& alpha) { typedef typename PFP::VEC3 VEC3 ; typedef typename PFP::REAL REAL ; const VEC3& p1 = position[e.dart]; const VEC3& p2 = position[map.phi1(e.dart)]; if(Geom::isPointInSphere(p1, center, radius) && !Geom::isPointInSphere(p2, center, radius)) { VEC3 p = p1 - center; VEC3 qminusp = p2 - center - p; REAL s = p * qminusp; REAL n2 = qminusp.norm2(); alpha = (- s + sqrt(s*s + n2 * (radius*radius - p.norm2()))) / n2; return true ; } return false ; }
void RasGouraud::DoPerVertexLighting( VertexBuffer& workingVB, FaceList& workingFaces, RenderObject& obj ) { ///Gouraud shade基于逐顶点法线 for (size_t iVert=0; iVert<workingVB.size(); ++iVert) { SVertex& vert = workingVB[iVert]; if(!vert.bActive) continue; //在世界空间进行光照 VEC3 worldNormal = Common::Transform_Vec3_By_Mat44(vert.normal, obj.m_matWorldIT, false).GetVec3(); worldNormal.Normalize(); SColor tmp; RenderUtil::DoLambertLighting(tmp, worldNormal, g_env.renderer->m_testLight.neg_dir, obj.m_pMaterial); vert.color *= tmp; } }
Intersection intersectionSegmentHalfPlan(const VEC3& PA, const VEC3& PB, const VEC3& P, const VEC3& DirP, const VEC3& OrientP)//, VEC3& Inter) { VEC3 NormP = (DirP-P) ^ (OrientP-P) ; NormP.normalize() ; //intersection SegmentPlan Intersection inter = intersectionSegmentPlan(PA,PB,P,NormP); if(inter == EDGE_INTERSECTION) { //and one of the two points must be in the right side of the line return intersectionSegmentPlan(PA,PB, P, OrientP); } else { return inter; } }
VEC3 operator* (const float scalar, VEC3& v) { return(VEC3(scalar * v.x(), scalar * v.y(), scalar * v.z())); }
Intersection intersectionSegmentTriangle(const VEC3& PA, const VEC3& PB, const VEC3& Ta, const VEC3& Tb, const VEC3& Tc, VEC3& Inter) { typedef typename VEC3::DATA_TYPE T ; const T precision = 0.0001;//std::numeric_limits<T>::min(); VEC3 u = Tb - Ta ; VEC3 v = Tc - Ta ; VEC3 Dir = PB - PA ; VEC3 n = u ^ v ; VEC3 w0 = PA - Ta ; float a = -(n * w0) ; float b = (n * Dir) ; if(fabs(b) < precision) //ray parallel to triangle return NO_INTERSECTION ; //compute intersection T r = a / b ; if((r < -precision) || (r > (T(1) + precision))) return NO_INTERSECTION; Inter = PA + r * Dir; // intersect point of ray and plane // is I inside T? T uu = u.norm2() ; T uv = u * v ; T vv = v.norm2() ; VEC3 w = Inter - Ta ; T wu = w * u ; T wv = w * v ; T D = (uv * uv) - (uu * vv) ; // get and test parametric coords T s = ((uv * wv) - (vv * wu)) / D ; if(s <= precision) s = 0.0f; if(s < T(0) || s > T(1)) return NO_INTERSECTION ; T t = ((uv * wu) - (uu * wv)) / D ; if(t <= precision) t = 0.0f; if(t < T(0) || (s + t) > T(1)) return NO_INTERSECTION ; if((s == T(0) || s == T(1))) if(t == T(0) || t == T(1)) return VERTEX_INTERSECTION ; else return EDGE_INTERSECTION ; else if(t == T(0) || t == T(1)) return EDGE_INTERSECTION ; return FACE_INTERSECTION ; }
VEC3 cross(const VEC3& a, const VEC3& b) { float x = (a.y()*b.z())-(b.y()*a.z()); float y = (a.z()*b.x())-(b.z()*b.x()); float z = (a.x()*b.y())-(b.x()*a.y()); return (VEC3(x, y, z)); }
//--------------------------------------------------------------------- bool TerrainQuadTreeNode::calculateCurrentLod(float cFactor) { mSelfOrChildRendered = false; // early-out /* disable this, could cause 'jumps' in LOD as children go out of frustum if (!cam->isVisible(mMovable->getWorldBoundingBox(true))) { mCurrentLod = -1; return mSelfOrChildRendered; } */ // Check children first int childRenderedCount = 0; if (!isLeaf()) { for (int i = 0; i < 4; ++i) { if (mChildren[i]->calculateCurrentLod(cFactor)) ++childRenderedCount; } } if (childRenderedCount == 0) { // no children were within their LOD ranges, so we should consider our own VEC3 localPos = g_env.pSceneMgr->GetCamera()->GetPos() - mLocalCentre - mTerrain->getPosition(); float dist; if (g_env.pSceneMgr->GetTerrainOptions()->getUseRayBoxDistanceCalculation()) { // Get distance to this terrain node (to closest point of the box) // head towards centre of the box (note, box may not cover mLocalCentre because of height) //VEC3 dir(mAABB.getCenter() - localPos); //dir.normalise(); //Ray ray(localPos, dir); //std::pair<bool, float> intersectRes = Math::intersects(ray, mAABB); //// ray will always intersect, we just want the distance //dist = intersectRes.second; _AST(0); } else { // distance to tile centre dist = localPos.GetLength(); // deduct half the radius of the box, assume that on average the // worst case is best approximated by this dist -= (mBoundingRadius * 0.5f); } // For each LOD, the distance at which the LOD will transition *downwards* // is given by // distTransition = maxDelta * cFactor; uint32 lodLvl = 0; mCurrentLod = -1; for (LodLevelList::iterator i = mLodLevels.begin(); i != mLodLevels.end(); ++i, ++lodLvl) { // If we have no parent, and this is the lowest LOD, we always render // this is the 'last resort' so to speak, we always enoucnter this last if (lodLvl+1 == mLodLevels.size() && !mParent) { mCurrentLod = lodLvl; mSelfOrChildRendered = true; mLodTransition = 0; } else { // check the distance LodLevel* ll = *i; // Calculate or reuse transition distance float distTransition; if (Common::Equal(cFactor, ll->lastCFactor)) distTransition = ll->lastTransitionDist; else { distTransition = ll->maxHeightDelta * cFactor; ll->lastCFactor = cFactor; ll->lastTransitionDist = distTransition; } if (dist < distTransition) { // we're within range of this LOD mCurrentLod = lodLvl; mSelfOrChildRendered = true; if (mTerrain->_getMorphRequired()) { // calculate the transition percentage // we need a percentage of the total distance for just this LOD, // which means taking off the distance for the next higher LOD // which is either the previous entry in the LOD list, // or the largest of any children. In both cases these will // have been calculated before this point, since we process // children first. Distances at lower LODs are guaranteed // to be larger than those at higher LODs float distTotal = distTransition; if (isLeaf()) { // Any higher LODs? if (i != mLodLevels.begin()) { LodLevelList::iterator prev = i - 1; distTotal -= (*prev)->lastTransitionDist; } } else { // Take the distance of the lowest LOD of child const LodLevel* childLod = mChildWithMaxHeightDelta->getLodLevel( mChildWithMaxHeightDelta->getLodCount()-1); distTotal -= childLod->lastTransitionDist; } // fade from 0 to 1 in the last 25% of the distance float distMorphRegion = distTotal * 0.25f; float distRemain = distTransition - dist; mLodTransition = 1.0f - (distRemain / distMorphRegion); mLodTransition = std::min(1.0f, mLodTransition); mLodTransition = std::max(0.0f, mLodTransition); // Pass both the transition % and target LOD (GLOBAL current + 1) // this selectively applies the morph just to the // vertices which would drop out at this LOD, even // while using the single shared vertex data mTerrain->m_cbTerrain.lodMorph = VEC2(mLodTransition, mCurrentLod + mBaseLod + 1); } // since LODs are ordered from highest to lowest detail, // we can stop looking now break; } } } } else { // we should not render ourself mCurrentLod = -1; mSelfOrChildRendered = true; if (childRenderedCount < 4) { // only *some* children decided to render on their own, but either // none or all need to render, so set the others manually to their lowest for (int i = 0; i < 4; ++i) { TerrainQuadTreeNode* child = mChildren[i]; if (!child->isSelfOrChildRenderedAtCurrentLod()) { child->setCurrentLod(child->getLodCount()-1); child->setLodTransition(1.0); } } } // (childRenderedCount < 4) } // (childRenderedCount == 0) return mSelfOrChildRendered; }