Exemple #1
0
    TextureResult HosekWilkieSky(const BufferUploads::TextureDesc& desc, const ParameterBox& parameters)
    {
            // The "turbidity" parameter is Linke’s turbidity factor. Hosek and Wilkie give these example parameters:
            //      T = 2 yields a very clear, Arctic-like sky
            //      T = 3 a clear sky in a temperate climate
            //      T = 6 a sky on a warm, moist day
            //      T = 10 a slightly hazy day
            //      T > 50 represent dense fog

        auto defaultSunDirection = Normalize(Float3(1.f, 1.f, 0.33f));
        Float3 sunDirection = parameters.GetParameter<Float3>(ParameterBox::ParameterNameHash("SunDirection"), defaultSunDirection);
        sunDirection = Normalize(sunDirection);

        auto turbidity = (double)parameters.GetParameter(ParameterBox::ParameterNameHash("turbidity"), 3.f);
        auto albedo = (double)parameters.GetParameter(ParameterBox::ParameterNameHash("albedo"), 0.1f);
        auto elevation = (double)Deg2Rad(parameters.GetParameter(ParameterBox::ParameterNameHash("elevation"), XlASin(sunDirection[2])));
        auto* state = arhosek_rgb_skymodelstate_alloc_init(turbidity, albedo, elevation);

        auto pixels = std::make_unique<Float4[]>(desc._width*desc._height);
        for (unsigned y=0; y<desc._height; ++y)
            for (unsigned x=0; x<desc._width; ++x) {
                auto p = y*desc._width+x;
                pixels[p] = Float4(0.f, 0.f, 0.f, 1.f);

                Float3 direction(0.f, 0.f, 0.f);
                bool hitPanel = false;

                for (unsigned c = 0; c < 6; ++c) {
                    Float2 tc(x / float(desc._width), y / float(desc._height));
                    auto tcMins = s_verticalPanelCoords[c][0];
                    auto tcMaxs = s_verticalPanelCoords[c][1];
                    if (tc[0] >= tcMins[0] && tc[1] >= tcMins[1] && tc[0] <  tcMaxs[0] && tc[1] <  tcMaxs[1]) {
                        tc[0] = 2.0f * (tc[0] - tcMins[0]) / (tcMaxs[0] - tcMins[0]) - 1.0f;
                        tc[1] = 2.0f * (tc[1] - tcMins[1]) / (tcMaxs[1] - tcMins[1]) - 1.0f;

                        hitPanel = true;
                        auto plusX = s_verticalPanels[c][0];
                        auto plusY = s_verticalPanels[c][1];
                        auto center = s_verticalPanels[c][2];
                        direction = center + plusX * tc[0] + plusY * tc[1];
                    }
                }

                if (hitPanel) {
                    auto theta = CartesianToSpherical(direction)[0];
                    theta = std::min(.4998f * gPI, theta);
                    auto gamma = XlACos(std::max(0.f, Dot(Normalize(direction), sunDirection)));

                    auto R = arhosek_tristim_skymodel_radiance(state, theta, gamma, 0);
                    auto G = arhosek_tristim_skymodel_radiance(state, theta, gamma, 1);
                    auto B = arhosek_tristim_skymodel_radiance(state, theta, gamma, 2);

                    pixels[p][0] = (float)R;
                    pixels[p][1] = (float)G;
                    pixels[p][2] = (float)B;
                }
            }

        arhosekskymodelstate_free(state);

        return TextureResult
            {
                BufferUploads::CreateBasicPacket(
                    (desc._width*desc._height)*sizeof(Float4),
                    pixels.get(),
                    BufferUploads::TexturePitches(desc._width*sizeof(Float4), desc._width*desc._height*sizeof(Float4))),
                RenderCore::Metal::NativeFormat::R32G32B32A32_FLOAT,
                UInt2(desc._width, desc._height)
            };
    }
Exemple #2
0
vec Plane::ProjectToPositiveHalf(const vec &point) const
{
	return point - Min(0.f, (Dot(normal, point) - d)) * normal;
}
Exemple #3
0
float Plane::DihedralAngle(const Plane &plane) const
{
	return Dot(normal, plane.normal);
}
	Vector2 TransformPoint(Mat3Param matrix, Vec2Param vector)
	{
		float x = Dot(*(Vector2*)&matrix[0], vector) + matrix[0][2];
		float y = Dot(*(Vector2*)&matrix[1], vector) + matrix[1][2];
		return Vector2(x, y);
	}
Exemple #5
0
void PerceptionModule::UpdatePerception()
{
	const float viewDistanceSqr = mViewDistance*mViewDistance;
	const float viewSpan = cos(mViewAngle * 0.5f);

	//const AgentList& agents = mOwner.GetWorld().GetAgentList();
	const std::vector<Agent*> agents = mOwner.GetWorld().GetAgents();

	//AgentList::const_iterator iter = agents.begin();
	int size = agents.size();
	//for(; iter!= agents.end(); ++iter)
	for (int i = 0; i < size; ++i)
	{
		const Agent* agent = agents[i]; //(*iter);
		// Ignore self
		if (&mOwner == agent)
		{
			continue;
		}

		// Check if agent is in range
		const SVector2 ownerToTarget = agent->GetPosition() - mOwner.GetPosition();
		const float distanceSqr = LengthSquared(ownerToTarget);
		if (distanceSqr > viewDistanceSqr)
		{
			continue;
		}

		// Check if agent is in view cone
		const SVector2 dirToTarget = Normalize(ownerToTarget);
		const float dot = Dot(mOwner.GetHeading(), dirToTarget);
		if (dot < viewSpan)
		{
			continue;
		}

		// Check if we have line of site
		if (!mOwner.GetWorld().HasLOS(mOwner.GetPosition(), agent->GetPosition()))
		{
			continue;
		}

		// Check if we have a record for this agent
		bool hasRecord = false;
		MemoryRecords::iterator memoryIter = mMemoryRecords.begin();
		while (memoryIter != mMemoryRecords.end())
		{
			PerceptionData& record = (*memoryIter);
			if (record.pAgent == agent)
			{
				record.lastSeenLocation = agent->GetPosition();
				record.lastRecordedTime = 0.0f;
				record.level = Confirm;
				hasRecord = true;
				break;
			}
			++memoryIter;
		}

		// Add a new record if agent is new
		if (!hasRecord)
		{
			PerceptionData newRecord;
			newRecord.pAgent = agent;
			newRecord.lastSeenLocation = agent->GetPosition();
			newRecord.lastRecordedTime = 0.0f;
			newRecord.level = Confirm;
			mMemoryRecords.push_back(newRecord);
		}
	}
}
Exemple #6
0
	Vec4f PlaneEquation(void) const
	{
		return Vec4f(Normal(), -Dot(Normal(), _point));
	}
Exemple #7
0
void
DMCWOS::advanceWalkerByWalker(BRANCHER& Branch)
{
    //Pooma::Clock timer;
    RealType oneovertau = 1.0/Tau;
    RealType oneover2tau = 0.5*oneovertau;
    RealType g = sqrt(Tau);
    RealType vwos;
    //MCWalkerConfiguration::PropertyContainer_t Properties;
    int nh = H.size()+1;
    // extract the WOS potential
    //WOSPotential* wos = dynamic_cast<WOSPotential*>(H.getHamiltonian("wos"));
    MCWalkerConfiguration::iterator it = W.begin();
    MCWalkerConfiguration::iterator it_end = W.end();
    while(it != it_end)
    {
        (*it)->Properties(WEIGHT) = 1.0;
        (*it)->Properties(MULTIPLICITY) = 1.0;
        //copy the properties of the working walker
        W.Properties = (*it)->Properties;
        //save old local energy
        ValueType eold = W.Properties(LOCALENERGY);
        /*
        If doing WOS then we have to redo the old calculation for ROld to
        calculate G(Rold,Rnew). So we extract wos from the Hamiltonian and
        re-evaluate it.
        */
        ValueType emixed = eold;
        if(wos_ref)
        {
            W.R = (*it)->R;
            DistanceTable::update(W);
            ValueType psi(Psi.evaluateLog(W));//not used anyway
            eold = H.evaluate(W);
            emixed += 0.5*W.Properties(WOSVAR)*Tau_var;
        }
        //ValueType emixed = eold + 0.5*W.Properties(WOSVAR)*Tau;
        //create a 3N-Dimensional Gaussian with variance=1
        makeGaussRandom(deltaR);
        W.R = g*deltaR + (*it)->R + (*it)->Drift;
        //update the distance table associated with W
        DistanceTable::update(W);
        //evaluate wave function
        ValueType logpsi(Psi.evaluateLog(W));
        //update the properties
        W.Properties(LOCALENERGY) = H.evaluate(W);
        W.Properties(LOGPSI) =logpsi;
        W.Properties(SIGN) = Psi.getSign();
        bool accepted=false;
        //deltaR = W.R - (*it)->R - (*it)->Drift;
        //RealType forwardGF = exp(-oneover2tau*Dot(deltaR,deltaR));
        //RealType forwardGF = exp(-0.5*Dot(deltaR,deltaR));
        RealType logGf = -0.5*Dot(deltaR,deltaR);
        //scale the drift term to prevent persistent cofigurations
        ValueType vsq = Dot(W.G,W.G);
        //converting gradients to drifts, D = tau*G (reuse G)
        //   W.G *= Tau;//original implementation with bare drift
        ValueType scale = ((-1.0+sqrt(1.0+2.0*Tau*vsq))/vsq);
        drift = scale*W.G;
        deltaR = (*it)->R - W.R - drift;
        //RealType backwardGF = exp(-oneover2tau*Dot(deltaR,deltaR));
        RealType logGb = -oneover2tau*Dot(deltaR,deltaR);
        //set acceptance probability
        //RealType prob= std::min(backwardGF/forwardGF*W.Properties(PSISQ)/(*it)->Properties(PSISQ),1.0);
        //RealType prob= std::min(exp(logGb-logGf)*W.Properties(PSISQ)/(*it)->Properties(PSISQ),1.0);
        RealType prob= std::min(exp(logGb-logGf +2.0*(W.Properties(LOGPSI)-(*it)->Properties(LOGPSI))),1.0);
        if(Random() > prob)
        {
            (*it)->Properties(AGE)++;
            emixed += emixed;
        }
        else
        {
            accepted=true;
            W.Properties(AGE) = 0;
            (*it)->R = W.R;
            (*it)->Drift = drift;
            (*it)->Properties = W.Properties;
            H.copy((*it)->getEnergyBase());
            emixed += W.Properties(LOCALENERGY) + 0.5*W.Properties(WOSVAR)*Tau_var;
        }
        //calculate the weight and multiplicity
        ValueType M = Branch.branchGF(Tau,emixed*0.5,1.0-prob);
        if((*it)->Properties(AGE) > 3.0)
            M = min(0.5,M);
        if((*it)->Properties(AGE) > 0.9)
            M = min(1.0,M);
        (*it)->Properties(WEIGHT) = M;
        (*it)->Properties(MULTIPLICITY) = M + Random();
        //node-crossing: kill it for the time being
        if(Branch(W.Properties(SIGN),(*it)->Properties(SIGN)))
        {
            accepted=false;
            (*it)->Properties(WEIGHT) = 0.0;
            (*it)->Properties(MULTIPLICITY) = 0.0;
        }
        /*
        if(Branch(W.Properties(PSI),(*it)->Properties(PSI))) {
        accepted=false;
        (*it)->Properties(WEIGHT) = 0.0;
        (*it)->Properties(MULTIPLICITY) = 0.0;
        } else {

        RealType logGf = -0.5*Dot(deltaR,deltaR);

        ValueType vsq = Dot(W.G,W.G);
        ValueType scale = ((-1.0+sqrt(1.0+2.0*Tau*vsq))/vsq);
        drift = scale*W.G;
        deltaR = (*it)->R - W.R - drift;
        RealType logGb = -oneover2tau*Dot(deltaR,deltaR);

        RealType prob
        = std::min(exp(logGb-logGf)*W.Properties(PSISQ)/(*it)->Properties(PSISQ),1.0);

        if(Random() > prob){
        (*it)->Properties(AGE)++;
        emixed += emixed;
        } else {
        accepted=true;
        W.Properties(AGE) = 0;
        (*it)->R = W.R;
        (*it)->Drift = drift;
        (*it)->Properties = W.Properties;
        // H.update(W.Energy[(*it)->ID]);
        //H.get((*it)->E);
        H.copy((*it)->getEnergyBase());
        emixed += W.Properties(LOCALENERGY) + 0.5*W.Properties(WOSVAR)*Tau_var;
        }

        //calculate the weight and multiplicity
        ValueType M = Branch.branchGF(Tau,emixed*0.5,1.0-prob);
        if((*it)->Properties(AGE) > 3.0) M = min(0.5,M);
        if((*it)->Properties(AGE) > 0.9) M = min(1.0,M);
        (*it)->Properties(WEIGHT) = M;
        (*it)->Properties(MULTIPLICITY) = M + Random();
        }
        */
        if(accepted)
            ++nAccept;
        else
            ++nReject;
        ++it;
    }
}
Exemple #8
0
Float MicrofacetReflection::Pdf(const Vector3f &wo, const Vector3f &wi) const {
    if (!SameHemisphere(wo, wi)) return 0;
    Vector3f wh = Normalize(wo + wi);
    return distribution->Pdf(wo, wh) / (4 * Dot(wo, wh));
}
Exemple #9
0
Float FresnelBlend::Pdf(const Vector3f &wo, const Vector3f &wi) const {
    if (!SameHemisphere(wo, wi)) return 0;
    Vector3f wh = Normalize(wo + wi);
    Float pdf_wh = distribution->Pdf(wo, wh);
    return .5f * (AbsCosTheta(wi) * InvPi + pdf_wh / (4 * Dot(wo, wh)));
}
Exemple #10
0
		void Reflect(const Vector2D &v,
			const Vector2D &normal, Vector2D *result)
		{
			*result = (v - (normal * Dot(v, normal) * 2.0f));
		}
Exemple #11
0
		Float Reflect(Float direction, const Vector2D &normal) {
			Vector2D v(cos(direction), sin(direction));
			v = (v - (normal * Dot(v, normal) * Vector2D(2.0f, 2.0f)));
			return atan2(v.mY, v.mX);
		}
Exemple #12
0
		Vector2D Reflect(const Vector2D &v, const Vector2D &normal) {
			return (v - (normal * Dot(v, normal) * 2.0f));
		}
Exemple #13
0
void VoxelRenderer::Flush(RenderContext& renderContext,
                          const SceneConstants& sceneConstants)
{
    //  Set up global shader constants
    m_constants.projectionViewMatrix = sceneConstants.viewMatrix *
                                       sceneConstants.projectionMatrix;
    m_constants.clipPlane = sceneConstants.clipPlane;

    //  Calculate camera distances for all queued render ops
    float3 cameraPos = sceneConstants.cameraPos;
    for (size_t i = 0; i < m_renderOps.size(); ++i)
    {
        float3 diff = m_renderOps[i].position - cameraPos;
        m_renderOps[i].distance2 = Dot(diff, diff);
    }
    for (size_t i = 0; i < m_gapFillerRenderOps.size(); ++i)
    {
        float3 diff = m_gapFillerRenderOps[i].position - cameraPos;
        m_gapFillerRenderOps[i].distance2 = Dot(diff, diff);
    }
    for (size_t i = 0; i < m_transparentRenderOps.size(); ++i)
    {
        float3 diff = m_transparentRenderOps[i].position - cameraPos;
        m_transparentRenderOps[i].distance2 = Dot(diff, diff);
    }
    
    //  Sort by camera distance (front to back for opaque render ops,
    //  back to front for transparent)
    auto transparentSorter = [](const RenderOp& lhs, const RenderOp& rhs)
    {
        return lhs.distance2 > rhs.distance2;
    };
    auto opaqueSorter = [](const RenderOp& lhs, const RenderOp& rhs)
    {
        return lhs.distance2 < rhs.distance2;
    };
    std::sort(m_renderOps.begin(), m_renderOps.end(), opaqueSorter);
    std::sort(m_gapFillerRenderOps.begin(), m_gapFillerRenderOps.end(), opaqueSorter);
    std::sort(m_transparentRenderOps.begin(), m_transparentRenderOps.end(), transparentSorter);

    //  Finally time to draw them
    renderContext.PushDepthStencilState(m_shared->depthStencilState);
    for (size_t i = 0; i < m_renderOps.size(); i++)
    {
        Draw(m_renderOps[i]);
    }
    m_renderOps.clear();
    renderContext.PopDepthStencilState();

    renderContext.PushDepthStencilState(m_shared->fillGapsDepthStencilState);
    for (size_t i = 0; i < m_gapFillerRenderOps.size(); ++i)
    {
        Draw(m_gapFillerRenderOps[i]);
    }
    m_gapFillerRenderOps.clear();
    renderContext.PopDepthStencilState();

    renderContext.PushDepthStencilState(m_shared->transparentDepthStencilState);
    renderContext.PushBlendState(m_shared->blendState);
    for (size_t i = 0; i < m_transparentRenderOps.size(); i++)
    {
        Draw(m_transparentRenderOps[i]);
    }
    m_transparentRenderOps.clear();
    renderContext.PopBlendState();
    renderContext.PopDepthStencilState();
}
Exemple #14
0
bool Polyhedron::FaceContains(int faceIndex, const float3 &worldSpacePoint, float polygonThickness) const
{
	// N.B. This implementation is a duplicate of Polygon::Contains, but adapted to avoid dynamic memory allocation
	// related to converting the face of a Polyhedron to a Polygon object.

	// Implementation based on the description from http://erich.realtimerendering.com/ptinpoly/

	const Face &face = f[faceIndex];
	const std::vector<int> &vertices = face.v;

	if (vertices.size() < 3)
		return false;

	Plane p = FacePlane(faceIndex);
	if (FacePlane(faceIndex).Distance(worldSpacePoint) > polygonThickness)
		return false;

	int numIntersections = 0;

	float3 basisU = v[vertices[1]] - v[vertices[0]];
	basisU.Normalize();
	float3 basisV = Cross(p.normal, basisU).Normalized();
	mathassert(basisU.IsNormalized());
	mathassert(basisV.IsNormalized());
	mathassert(basisU.IsPerpendicular(basisV));
	mathassert(basisU.IsPerpendicular(p.normal));
	mathassert(basisV.IsPerpendicular(p.normal));

	float2 localSpacePoint = float2(Dot(worldSpacePoint, basisU), Dot(worldSpacePoint, basisV));

	const float epsilon = 1e-4f;

	float2 p0 = float2(Dot(v[vertices.back()], basisU), Dot(v[vertices.back()], basisV)) - localSpacePoint;
	if (Abs(p0.y) < epsilon)
		p0.y = -epsilon; // Robustness check - if the ray (0,0) -> (+inf, 0) would pass through a vertex, move the vertex slightly.
	for(size_t i = 0; i < vertices.size(); ++i)
	{
		float2 p1 = float2(Dot(v[vertices[i]], basisU), Dot(v[vertices[i]], basisV)) - localSpacePoint;
		if (Abs(p1.y) < epsilon)
			p0.y = -epsilon; // Robustness check - if the ray (0,0) -> (+inf, 0) would pass through a vertex, move the vertex slightly.

		if (p0.y * p1.y < 0.f)
		{
			if (p0.x > 1e-3f && p1.x > 1e-3f)
				++numIntersections;
			else
			{
				// P = p0 + t*(p1-p0) == (x,0)
				//     p0.x + t*(p1.x-p0.x) == x
				//     p0.y + t*(p1.y-p0.y) == 0
				//                 t == -p0.y / (p1.y - p0.y)

				// Test whether the lines (0,0) -> (+inf,0) and p0 -> p1 intersect at a positive X-coordinate.
				float2 d = p1 - p0;
				if (Abs(d.y) > 1e-5f)
				{
					float t = -p0.y / d.y;
					float x = p0.x + t * d.x;
					if (t >= 0.f && t <= 1.f && x > 1e-6f)
						++numIntersections;
				}
			}
		}
		p0 = p1;
	}

	return numIntersections % 2 == 1;
}
  bool DMCParticleByParticle::run() { 

    //add columns
    IndexType PopIndex = Estimators->addColumn("Population");
    IndexType EtrialIndex = Estimators->addColumn("E_T");
    //write the header
    Estimators->reportHeader();

    MolecuFixedNodeBranch<RealType> brancher(Tau,W.getActiveWalkers());
    //initialize parameters for fixed-node branching
    brancher.put(qmcNode,LogOut);

    if(BranchInfo != "default")  brancher.read(BranchInfo);
    else {
      /*if VMC/DMC directly preceded DMC (Counter > 0) then
        use the average value of the energy estimator for
        the reference energy of the brancher*/
      if(Counter) {
        RealType e_ref = W.getLocalEnergy();
        LOGMSG("Overwriting the reference energy by the local energy " << e_ref)  
        brancher.setEguess(e_ref);
      }
    }
    
    MCWalkerConfiguration::iterator it(W.begin()); 
    MCWalkerConfiguration::iterator it_end(W.end()); 
    while(it!=it_end) {
      (*it)->Properties(WEIGHT) = 1.0;
      (*it)->Properties(MULTIPLICITY) = 1.0;
      ++it;
    }

    //going to add routines to calculate how much we need
    bool require_register =  W.createAuxDataSet();
    int iwalker=0;
    it = W.begin();
    it_end = W.end();
    if(require_register) {
      while(it != it_end) {
        W.DataSet[iwalker]->rewind();
        W.registerData(**it,*(W.DataSet[iwalker]));
        Psi.registerData(W,*(W.DataSet[iwalker]));
        ++it;++iwalker;
      } 
    }      

    Estimators->reset();
    
    IndexType block = 0;
    
    Pooma::Clock timer;
    int Population = W.getActiveWalkers();
    int tPopulation = W.getActiveWalkers();
    RealType Eest = brancher.E_T;
    RealType E_T = Eest;
    RealType oneovertau = 1.0/Tau;
    RealType oneover2tau = 0.5*oneovertau;
    RealType g = sqrt(Tau);
    
    MCWalkerConfiguration::PropertyContainer_t Properties;
    ParticleSet::ParticlePos_t deltaR(W.getTotalNum());
    ParticleSet::ParticleGradient_t G(W.getTotalNum()), dG(W.getTotalNum());
    ParticleSet::ParticleLaplacian_t L(W.getTotalNum()), dL(W.getTotalNum());

    IndexType accstep=0;
    IndexType nAcceptTot = 0;
    IndexType nRejectTot = 0;
    IndexType nat = W.getTotalNum();

    int ncross = 0;
    do {
      IndexType step = 0;
      timer.start();
      nAccept = 0; nReject=0;
      IndexType nAllRejected = 0;
      do {
        Population = W.getActiveWalkers();

        it = W.begin();	 
        it_end = W.end();

        iwalker=0; 
        while(it != it_end) {

          MCWalkerConfiguration::WalkerData_t& w_buffer = *(W.DataSet[iwalker]);

          (*it)->Properties(WEIGHT) = 1.0;
          (*it)->Properties(MULTIPLICITY) = 1.0;
          //save old local energy
          ValueType eold((*it)->Properties(LOCALENERGY));
          ValueType emixed(eold);

          W.R = (*it)->R;
          w_buffer.rewind();
          W.copyFromBuffer(w_buffer);
          Psi.copyFromBuffer(W,w_buffer);

          ValueType psi_old((*it)->Properties(SIGN));
          ValueType psi(psi_old);

          //create a 3N-Dimensional Gaussian with variance=1
          makeGaussRandom(deltaR);
          bool notcrossed(true);
          int nAcceptTemp(0);
          int nRejectTemp(0);

          int iat=0;
          while(notcrossed && iat<nat){

            PosType dr(g*deltaR[iat]+(*it)->Drift[iat]);
            PosType newpos(W.makeMove(iat,dr));
            RealType ratio(Psi.ratio(W,iat,dG,dL));

            if(ratio < 0.0) {//node is crossed, stop here
              notcrossed = false;
            } else {
      	      G = W.G+dG;
      	      RealType logGf = -0.5*dot(deltaR[iat],deltaR[iat]);
      	      
      	      ValueType vsq = Dot(G,G);
      	      ValueType scale = ((-1.0+sqrt(1.0+2.0*Tau*vsq))/vsq);
      	      dr = (*it)->R[iat]-newpos-scale*G[iat]; 
      	      //dr = (*it)->R[iat]-newpos-Tau*G[iat]; 
      	      RealType logGb = -oneover2tau*dot(dr,dr);
      	      
      	      //RealType ratio2 = pow(ratio,2)
      	      RealType prob = std::min(1.0,pow(ratio,2)*exp(logGb-logGf));
      	      if(Random() < prob) { 
      	        ++nAcceptTemp;
      	        W.acceptMove(iat);
      	        Psi.update2(W,iat);
      	        W.G = G;
      	        W.L += dL;
      	        //  (*it)->Drift = Tau*G;
      	        (*it)->Drift = scale*G;
      	      } else {
      	        ++nRejectTemp; 
      	        Psi.restore(iat);
      	      }
            } 
            ++iat;
          }

          if(notcrossed) {
            if(nAcceptTemp) {//need to overwrite the walker properties
      	      w_buffer.rewind();
      	      W.copyToBuffer(w_buffer);
      	      psi = Psi.evaluate(W,w_buffer);
      	      (*it)->R = W.R;
      	      (*it)->Properties(AGE) = 0;
                    //This is not so useful: allow overflow/underflow
      	      (*it)->Properties(LOGPSI) = log(fabs(psi));
      	      (*it)->Properties(SIGN) = psi;
      	      (*it)->Properties(LOCALENERGY) = H.evaluate(W);
      	      H.copy((*it)->getEnergyBase());
      	      (*it)->Properties(LOCALPOTENTIAL) = H.getLocalPotential();
      	      emixed += (*it)->Properties(LOCALENERGY);
                  } else {
      	      //WARNMSG("All the particle moves are rejected.")
                    (*it)->Properties(AGE)++;
      	      ++nAllRejected;
      	      emixed += eold;
            }
            
            ValueType M = brancher.branchGF(Tau,emixed*0.5,0.0);
            // if((*it)->Properties(AGE) > 3.0) M = min(0.5,M);
            //persistent configurations
            if((*it)->Properties(AGE) > 1.9) M = std::min(0.5,M);
            if((*it)->Properties(AGE) > 0.9) M = std::min(1.0,M);
            (*it)->Properties(WEIGHT) = M; 
            (*it)->Properties(MULTIPLICITY) = M + Random();
            nAccept += nAcceptTemp;
            nReject += nRejectTemp;
          } else {//set the weight and multiplicity to zero
            (*it)->Properties(WEIGHT) = 0.0; 
            (*it)->Properties(MULTIPLICITY) = 0.0;
            nReject += W.getTotalNum();//not make sense
          }

          ++it; ++iwalker;
        }

        ++step;++accstep;
        Estimators->accumulate(W);
        Eest = brancher.update(Population,Eest); 
        //E_T = brancher.update(Population,Eest);
        brancher.branch(accstep,W);
      } while(step<nSteps);
      
      //WARNMSG("The number of a complete rejectoin " << nAllRejected)
      timer.stop();
      nAcceptTot += nAccept;
      nRejectTot += nReject;
      
      Estimators->flush();
      
      Estimators->setColumn(PopIndex,static_cast<RealType>(Population));
      Estimators->setColumn(EtrialIndex,Eest); //E_T);
      Estimators->setColumn(AcceptIndex,
      		     static_cast<RealType>(nAccept)/static_cast<RealType>(nAccept+nReject));
      Estimators->report(accstep);
      
      Eest = Estimators->average(0);
      LogOut->getStream() << "Block " << block << " " << timer.cpu_time() << " Fixed_configs " 
      		    << static_cast<RealType>(nAllRejected)/static_cast<RealType>(step*W.getActiveWalkers()) << endl;
      if(pStride) {
        //create an output engine
        HDFWalkerOutput WO(RootName);
        WO.get(W); 
        brancher.write(WO.getGroupID());
      }
      nAccept = 0; nReject = 0;
      block++;
    } while(block<nBlocks);

    LogOut->getStream() 
      << "Ratio = " 
      << static_cast<double>(nAcceptTot)/static_cast<double>(nAcceptTot+nRejectTot)
      << endl;
    
    if(!pStride) {
      //create an output engine
      HDFWalkerOutput WO(RootName);
      WO.get(W); 
      brancher.write(WO.getGroupID());
    }
    
    Estimators->finalize();
    
    return true;
  }
double TorranceSparrowSpecular::_NDF(const Vector &N, const Vector &H) {
    double ndoth=Dot(N,H);
    double ndoth2=ndoth*ndoth;
    return exp(((ndoth2)-1)/(mM*mM*ndoth2))*(1/(M_PI*mM*mM*ndoth2*ndoth2));
}
Exemple #17
0
Spectrum IGIIntegrator::Li(const Scene *scene,
		const RayDifferential &ray, const Sample *sample,
		   float *alpha) const {
	Spectrum L(0.);
	Intersection isect;
	if (scene->Intersect(ray, &isect)) {
		if (alpha) *alpha = 1.;
		Vector wo = -ray.d;
		// Compute emitted light if ray hit an area light source
		L += isect.Le(wo);
		// Evaluate BSDF at hit point
		BSDF *bsdf = isect.GetBSDF(ray);
		const Point &p = bsdf->dgShading.p;
		const Normal &n = bsdf->dgShading.nn;
		L += UniformSampleAllLights(scene, p, n,
					    wo, bsdf, sample,
					    lightSampleOffset, bsdfSampleOffset,
					    bsdfComponentOffset);
		// Compute indirect illumination with virtual lights
		u_int lSet = min(u_int(sample->oneD[vlSetOffset][0] * nLightSets),
		                 nLightSets-1);
		for (u_int i = 0; i < virtualLights[lSet].size(); ++i) {
			const VirtualLight &vl = virtualLights[lSet][i];
			// Add contribution from _VirtualLight_ _vl_
			// Ignore light if it's too close to current point
			float d2 = DistanceSquared(p, vl.p);
			//if (d2 < .8 * minDist2) continue;
			float distScale = SmoothStep(.8 * minDist2, 1.2 * minDist2, d2);
			// Compute virtual light's tentative contribution _Llight_
			Vector wi = Normalize(vl.p - p);
			Spectrum f = distScale * bsdf->f(wo, wi);
			if (f.Black()) continue;
			float G = AbsDot(wi, n) * AbsDot(wi, vl.n) / d2;
			Spectrum Llight = indirectScale * f * G * vl.Le /
				virtualLights[lSet].size();
			Llight *= scene->Transmittance(Ray(p, vl.p - p));
			// Possibly skip shadow ray with Russian roulette
			if (Llight.y() < rrThreshold) {
				float continueProbability = .1f;
				if (RandomFloat() > continueProbability)
					continue;
				Llight /= continueProbability;
			}
			static StatsCounter vlsr("IGI Integrator", "Shadow Rays to Virtual Lights"); //NOBOOK
			++vlsr; //NOBOOK
			if (!scene->IntersectP(Ray(p, vl.p - p, RAY_EPSILON,
					1.f - RAY_EPSILON)))
				L += Llight;
		}
		// Trace rays for specular reflection and refraction
		if (specularDepth++ < maxSpecularDepth) {
			Vector wi;
			// Trace rays for specular reflection and refraction
			Spectrum f = bsdf->Sample_f(wo, &wi,
						BxDFType(BSDF_REFLECTION | BSDF_SPECULAR));
			if (!f.Black()) {
				// Compute ray differential _rd_ for specular reflection
				RayDifferential rd(p, wi);
				rd.hasDifferentials = true;
				rd.rx.o = p + isect.dg.dpdx;
				rd.ry.o = p + isect.dg.dpdy;
				// Compute differential reflected directions
				Normal dndx = bsdf->dgShading.dndu * bsdf->dgShading.dudx +
					bsdf->dgShading.dndv * bsdf->dgShading.dvdx;
				Normal dndy = bsdf->dgShading.dndu * bsdf->dgShading.dudy +
					bsdf->dgShading.dndv * bsdf->dgShading.dvdy;
				Vector dwodx = -ray.rx.d - wo, dwody = -ray.ry.d - wo;
				float dDNdx = Dot(dwodx, n) + Dot(wo, dndx);
				float dDNdy = Dot(dwody, n) + Dot(wo, dndy);
				rd.rx.d = wi -
					dwodx + 2 * Vector(Dot(wo, n) * dndx +
						 dDNdx * n);
				rd.ry.d = wi -
					dwody + 2 * Vector(Dot(wo, n) * dndy +
						 dDNdy * n);
				L += scene->Li(rd, sample) * f * AbsDot(wi, n);
			}
			f = bsdf->Sample_f(wo, &wi,
					   BxDFType(BSDF_TRANSMISSION | BSDF_SPECULAR));
			if (!f.Black()) {
				// Compute ray differential _rd_ for specular transmission
				RayDifferential rd(p, wi);
				rd.hasDifferentials = true;
				rd.rx.o = p + isect.dg.dpdx;
				rd.ry.o = p + isect.dg.dpdy;

				float eta = bsdf->eta;
				Vector w = -wo;
				if (Dot(wo, n) < 0) eta = 1.f / eta;

				Normal dndx = bsdf->dgShading.dndu * bsdf->dgShading.dudx + bsdf->dgShading.dndv * bsdf->dgShading.dvdx;
				Normal dndy = bsdf->dgShading.dndu * bsdf->dgShading.dudy + bsdf->dgShading.dndv * bsdf->dgShading.dvdy;

				Vector dwodx = -ray.rx.d - wo, dwody = -ray.ry.d - wo;
				float dDNdx = Dot(dwodx, n) + Dot(wo, dndx);
				float dDNdy = Dot(dwody, n) + Dot(wo, dndy);

				float mu = eta * Dot(w, n) - Dot(wi, n);
				float dmudx = (eta - (eta*eta*Dot(w,n))/Dot(wi, n)) * dDNdx;
				float dmudy = (eta - (eta*eta*Dot(w,n))/Dot(wi, n)) * dDNdy;

				rd.rx.d = wi + eta * dwodx - Vector(mu * dndx + dmudx * n);
				rd.ry.d = wi + eta * dwody - Vector(mu * dndy + dmudy * n);
				L += scene->Li(rd, sample) * f * AbsDot(wi, n);
			}
		}
		--specularDepth;
	}
	else {
		// Handle ray with no intersection
		if (alpha) *alpha = 0.;
		for (u_int i = 0; i < scene->lights.size(); ++i)
			L += scene->lights[i]->Le(ray);
		if (alpha && !L.Black()) *alpha = 1.;
		return L;
	}
	return L;
}
RGB TorranceSparrowSpecular::_Fresnel(const Vector &wo, const Vector &H) {
    RGB one(1,1,1);
    RGB f0=mAlbedo*mScaleFactor;
    return f0+(one-f0)*pow(1-Dot(H,wo),5);
}
RangeFit::RangeFit( ColourSet const* colours, int flags ) 
  : ColourFit( colours, flags )
{
	// initialise the metric
	bool perceptual = ( ( m_flags & kColourMetricPerceptual ) != 0 );
	if( perceptual )
		m_metric = Vec3( 0.2126f, 0.7152f, 0.0722f );
	else
		m_metric = Vec3( 1.0f );

	// initialise the best error
	m_besterror = FLT_MAX;

	// cache some values
	int const count = m_colours->GetCount();
	Vec3 const* values = m_colours->GetPoints();
	float const* weights = m_colours->GetWeights();
	
	// get the covariance matrix
	Sym3x3 covariance = ComputeWeightedCovariance( count, values, weights );
	
	// compute the principle component
	Vec3 principle = ComputePrincipleComponent( covariance );

	// get the min and max range as the codebook endpoints
	Vec3 start( 0.0f );
	Vec3 end( 0.0f );
	if( count > 0 )
	{
		float min, max;
		
		// compute the range
		start = end = values[0];
		min = max = Dot( values[0], principle );
		for( int i = 1; i < count; ++i )
		{
			float val = Dot( values[i], principle );
			if( val < min )
			{
				start = values[i];
				min = val;
			}
			else if( val > max )
			{
				end = values[i];
				max = val;
			}
		}
	}
			
	// clamp the output to [0, 1]
	Vec3 const one( 1.0f );
	Vec3 const zero( 0.0f );
	start = Min( one, Max( zero, start ) );
	end = Min( one, Max( zero, end ) );

	// clamp to the grid and save
	Vec3 const grid( 31.0f, 63.0f, 31.0f );
	Vec3 const gridrcp( 1.0f/31.0f, 1.0f/63.0f, 1.0f/31.0f );
	Vec3 const half( 0.5f );
	m_start = Truncate( grid*start + half )*gridrcp;
	m_end = Truncate( grid*end + half )*gridrcp;
}
RGB TorranceSparrowSpecular::f(const Intersection &sr, const Vector &wi, const Vector &wo) {
    Vector half=Normalize(wi + wo);
    return mAlbedo/(4*M_PI*Dot(sr.normal,wi))*_NDF(sr.normal,half)*_Fresnel(wo,half)*_G(sr.normal,half,wi,wo);
}
  /** advance all the walkers with killnode==no
   * @param nat number of particles to move
   * 
   * When killnode==no, any move resulting in node-crossing is treated
   * as a normal rejection.
   */
  void DMCNonLocalUpdate::advanceWalkers(WalkerIter_t it, WalkerIter_t it_end,
      bool measure) 
  {

    //RealType plusFactor(Tau*Gamma);
    //RealType minusFactor(-Tau*(1.0-Alpha*(1.0+Gamma)));

    for(; it!=it_end; ++it)
    {
      Walker_t& thisWalker(**it);

      //save old local energy
      RealType eold    = thisWalker.Properties(LOCALENERGY);
      RealType signold = thisWalker.Properties(SIGN);
      RealType enew  = eold;

      //create a 3N-Dimensional Gaussian with variance=1
      makeGaussRandomWithEngine(deltaR,RandomGen);

      W.R = m_sqrttau*deltaR + thisWalker.R + thisWalker.Drift;
      
      //update the distance table associated with W
      //DistanceTable::update(W);
      W.update();
      
      //evaluate wave function
      RealType logpsi(Psi.evaluateLog(W));

      nonLocalOps.reset();

      bool accepted=false; 
      if(branchEngine->phaseChanged(Psi.getPhase(),thisWalker.Properties(SIGN))) 
      {
        thisWalker.Age++;
        ++nReject;
      } 
      else 
      {
        //RealType enew(H.evaluate(W,nonLocalOps.Txy));
        enew=H.evaluate(W,nonLocalOps.Txy);
        RealType logGf = -0.5*Dot(deltaR,deltaR);
        setScaledDrift(Tau,W.G,drift);

        deltaR = (*it)->R - W.R - drift;
        RealType logGb = -m_oneover2tau*Dot(deltaR,deltaR);

        RealType prob= std::min(std::exp(logGb-logGf +2.0*(logpsi-thisWalker.Properties(LOGPSI))),1.0);
        if(RandomGen() > prob){
          thisWalker.Age++;
          ++nReject;
          enew=eold;
        } else {
          accepted=true;  
          thisWalker.R = W.R;
          thisWalker.Drift = drift;
          thisWalker.resetProperty(logpsi,Psi.getPhase(),enew);
          H.saveProperty(thisWalker.getPropertyBase());
          //emixed = (emixed+enew)*0.5;
          //eold=enew;
          ++nAccept;
        }
      }

      int ibar=nonLocalOps.selectMove(RandomGen());

      //make a non-local move
      if(ibar) {
        int iat=nonLocalOps.id(ibar);
        W.R[iat] += nonLocalOps.delta(ibar);
        W.update();
        logpsi=Psi.evaluateLog(W);
        setScaledDrift(Tau,W.G,thisWalker.Drift);
        thisWalker.resetProperty(logpsi,Psi.getPhase(),eold);
        thisWalker.R[iat] = W.R[iat];
        ++NonLocalMoveAccepted;
      } 

      thisWalker.Weight *= branchEngine->branchWeight(eold,enew);
      //branchEngine->accumulate(eold,1);
    }
  }
Exemple #22
0
inline void HermitianTridiagU
( Matrix<Complex<R> >& A, Matrix<Complex<R> >& t )
{
#ifndef RELEASE
    PushCallStack("HermitianTridiagU");
#endif
    const int tHeight = std::max(A.Height()-1,0);
#ifndef RELEASE
    if( A.Height() != A.Width() )
        throw std::logic_error("A must be square");
    if( t.Viewing() && (t.Height() != tHeight || t.Width() != 1) )
        throw std::logic_error("t is of the wrong size");
#endif
    typedef Complex<R> C;
    
    if( !t.Viewing() )
        t.ResizeTo( tHeight, 1 );

    // Matrix views 
    Matrix<C>
        ATL, ATR,  A00, a01,     A02,  a01T,
        ABL, ABR,  a10, alpha11, a12,  alpha01B,
                   A20, a21,     A22;

    // Temporary matrices
    Matrix<C> w01;

    PushBlocksizeStack( 1 );
    PartitionUpDiagonal
    ( A, ATL, ATR,
         ABL, ABR, 0 );
    while( ABR.Height()+1 < A.Height() )
    {
        RepartitionUpDiagonal
        ( ATL, /**/ ATR,  A00, a01,     /**/ A02,
               /**/       a10, alpha11, /**/ a12,
         /*************/ /**********************/
          ABL, /**/ ABR,  A20, a21,     /**/ A22 );

        PartitionUp
        ( a01, a01T,
               alpha01B, 1 );

        w01.ResizeTo( a01.Height(), 1 );
        //--------------------------------------------------------------------//
        const C tau = Reflector( alpha01B, a01T );
        const R epsilon1 = alpha01B.GetRealPart(0,0);
        t.Set(t.Height()-1-A22.Height(),0,tau);
        alpha01B.Set(0,0,C(1));

        Hemv( UPPER, tau, A00, a01, C(0), w01 );
        const C alpha = -tau*Dot( w01, a01 )/C(2);
        Axpy( alpha, a01, w01 );
        Her2( UPPER, C(-1), a01, w01, A00 );
        alpha01B.Set(0,0,epsilon1);
        //--------------------------------------------------------------------//

        SlidePartitionUpDiagonal
        ( ATL, /**/ ATR,  A00, /**/ a01,     A02,
         /*************/ /**********************/
               /**/       a10, /**/ alpha11, a12,
          ABL, /**/ ABR,  A20, /**/ a21,     A22 );
    }
    PopBlocksizeStack();
#ifndef RELEASE
    PopCallStack();
#endif
}
	Vector2 TransformNormal(Mat3Param matrix, Vec2Param normal)
	{
		float x = Dot(*(Vector2*)&matrix[0], normal);
		float y = Dot(*(Vector2*)&matrix[1], normal);
		return Vector2(x, y);
	}
Exemple #24
0
bool Sphere::Intersect(const Ray &r, Float *tHit, SurfaceInteraction *isect,
                       bool testAlphaTexture) const {
    Float phi;
    Point3f pHit;
    // Transform _Ray_ to object space
    Vector3f oErr, dErr;
    Ray ray = (*WorldToObject)(r, &oErr, &dErr);

    // Compute quadratic sphere coefficients

    // Initialize _EFloat_ ray coordinate values
    EFloat ox(ray.o.x, oErr.x), oy(ray.o.y, oErr.y), oz(ray.o.z, oErr.z);
    EFloat dx(ray.d.x, dErr.x), dy(ray.d.y, dErr.y), dz(ray.d.z, dErr.z);
    EFloat a = dx * dx + dy * dy + dz * dz;
    EFloat b = 2 * (dx * ox + dy * oy + dz * oz);
    EFloat c = ox * ox + oy * oy + oz * oz - EFloat(radius) * EFloat(radius);

    // Solve quadratic equation for _t_ values
    EFloat t0, t1;
    if (!Quadratic(a, b, c, &t0, &t1)) return false;

    // Check quadric shape _t0_ and _t1_ for nearest intersection
    if (t0.UpperBound() > ray.tMax || t1.LowerBound() <= 0) return false;
    EFloat tShapeHit = t0;
    if (tShapeHit.LowerBound() <= 0) {
        tShapeHit = t1;
        if (tShapeHit.UpperBound() > ray.tMax) return false;
    }

    // Compute sphere hit position and $\phi$
    pHit = ray((Float)tShapeHit);

    // Refine sphere intersection point
    pHit *= radius / Distance(pHit, Point3f(0, 0, 0));
    if (pHit.x == 0 && pHit.y == 0) pHit.x = 1e-5f * radius;
    phi = std::atan2(pHit.y, pHit.x);
    if (phi < 0) phi += 2 * Pi;

    // Test sphere intersection against clipping parameters
    if ((zMin > -radius && pHit.z < zMin) || (zMax < radius && pHit.z > zMax) ||
        phi > phiMax) {
        if (tShapeHit == t1) return false;
        if (t1.UpperBound() > ray.tMax) return false;
        tShapeHit = t1;
        // Compute sphere hit position and $\phi$
        pHit = ray((Float)tShapeHit);

        // Refine sphere intersection point
        pHit *= radius / Distance(pHit, Point3f(0, 0, 0));
        if (pHit.x == 0 && pHit.y == 0) pHit.x = 1e-5f * radius;
        phi = std::atan2(pHit.y, pHit.x);
        if (phi < 0) phi += 2 * Pi;
        if ((zMin > -radius && pHit.z < zMin) ||
            (zMax < radius && pHit.z > zMax) || phi > phiMax)
            return false;
    }

    // Find parametric representation of sphere hit
    Float u = phi / phiMax;
    Float theta = std::acos(Clamp(pHit.z / radius, -1, 1));
    Float v = (theta - thetaMin) / (thetaMax - thetaMin);

    // Compute sphere $\dpdu$ and $\dpdv$
    Float zRadius = std::sqrt(pHit.x * pHit.x + pHit.y * pHit.y);
    Float invZRadius = 1 / zRadius;
    Float cosPhi = pHit.x * invZRadius;
    Float sinPhi = pHit.y * invZRadius;
    Vector3f dpdu(-phiMax * pHit.y, phiMax * pHit.x, 0);
    Vector3f dpdv =
        (thetaMax - thetaMin) *
        Vector3f(pHit.z * cosPhi, pHit.z * sinPhi, -radius * std::sin(theta));

    // Compute sphere $\dndu$ and $\dndv$
    Vector3f d2Pduu = -phiMax * phiMax * Vector3f(pHit.x, pHit.y, 0);
    Vector3f d2Pduv =
        (thetaMax - thetaMin) * pHit.z * phiMax * Vector3f(-sinPhi, cosPhi, 0.);
    Vector3f d2Pdvv = -(thetaMax - thetaMin) * (thetaMax - thetaMin) *
                      Vector3f(pHit.x, pHit.y, pHit.z);

    // Compute coefficients for fundamental forms
    Float E = Dot(dpdu, dpdu);
    Float F = Dot(dpdu, dpdv);
    Float G = Dot(dpdv, dpdv);
    Vector3f N = Normalize(Cross(dpdu, dpdv));
    Float e = Dot(N, d2Pduu);
    Float f = Dot(N, d2Pduv);
    Float g = Dot(N, d2Pdvv);

    // Compute $\dndu$ and $\dndv$ from fundamental form coefficients
    Float invEGF2 = 1 / (E * G - F * F);
    Normal3f dndu = Normal3f((f * F - e * G) * invEGF2 * dpdu +
                             (e * F - f * E) * invEGF2 * dpdv);
    Normal3f dndv = Normal3f((g * F - f * G) * invEGF2 * dpdu +
                             (f * F - g * E) * invEGF2 * dpdv);

    // Compute error bounds for sphere intersection
    Vector3f pError = gamma(5) * Abs((Vector3f)pHit);

    // Initialize _SurfaceInteraction_ from parametric information
    *isect = (*ObjectToWorld)(SurfaceInteraction(pHit, pError, Point2f(u, v),
                                                 -ray.d, dpdu, dpdv, dndu, dndv,
                                                 ray.time, this));

    // Update _tHit_ for quadric intersection
    *tHit = (Float)tShapeHit;
    return true;
}
Exemple #25
0
Vector Vector::Reflect(Vector normal)
{
	return *this - (2 * Dot(normal) *normal);
}
Exemple #26
0
void GL3CalculateProjectionShadowMapMatrix(Vector3D viewp, Vector3D light_direction,
Vector3D x_direction, Vector3D y_direction, float zmin, float zmax) {
#if 0
    char *s1 = light_direction.GetString();
    char *s2 = x_direction.GetString();
    char *s3 = y_direction.GetString();
    sreMessage(SRE_MESSAGE_LOG, "GL3CalculateProjectionShadowMapMatrix: light_dir = %s, "
        "x_dir = %s, y_dir = %s, dot products: %f, %f, %f", s1, s2, s3,
        Dot(light_direction, x_direction), Dot(light_direction, y_direction),
        Dot(x_direction, y_direction));
    delete s1;
    delete s2;
    delete s3;
#endif
    Vector3D fvec = light_direction;
    Vector3D s = x_direction;
    Vector3D u = y_direction;
    Matrix4D M;
    // Note that the y direction has to be negated in order to preserve the handedness of
    // triangles when rendering the shadow map.
    M.Set(
        s.x, s.y, s.z, 0,
        - u.x, - u.y, - u.z, 0,
        - fvec.x, - fvec.y, - fvec.z, 0,
        0.0f, 0.0f, 0.0f, 1.0f);
    Matrix4D T;
    T.AssignTranslation(- viewp);
    // Calculate the projection matrix with a field of view of 90 degrees.
    float aspect = 1.0;
    float e = 1 / tanf((90.0 * M_PI / 180) / 2);
    float n = zmin;
    float f = zmax;
    float l = - n / e;
    float r = n / e;
    float b = - (1.0f / aspect) * n / e;
    float t = (1.0f / aspect) * n / e;
    Matrix4D projection_matrix;
    projection_matrix.Set(
        2 * n / (r - l), 0.0f, (r + l) / (r - l), 0.0f,
        0.0f, 2 * n / (t - b), (t + b) / (t - b), 0.0f,
        0.0f, 0.0f, - (f + n) / (f - n), - 2 * n * f / (f - n),
        0.0f, 0.0f, - 1.0f, 0.0f);
    projection_shadow_map_matrix = projection_matrix * (M * T);
    MatrixTransform shadow_map_viewport_matrix;
    shadow_map_viewport_matrix.Set(
        0.5f, 0.0f, 0.0f, 0.5f,
        0.0f, 0.5f, 0.0f, 0.5f,
        0.0f, 0.0f, 0.5f, 0.5f);
    projection_shadow_map_lighting_pass_matrix = shadow_map_viewport_matrix *
        projection_shadow_map_matrix;
//    projection_shadow_map_lighting_pass_matrix = projection_shadow_map_matrix;

#if 0
    Point3D P1 = viewp + light_direction * n;
    Point3D P2 = viewp + light_direction * f;
    Point3D P3 = viewp + light_direction * f + x_direction * f + y_direction * f;
    Vector4D P1_proj = projection_shadow_map_matrix * P1;
    Vector4D P2_proj = projection_shadow_map_matrix * P2;
    Vector4D P3_proj = projection_shadow_map_matrix * P3;
    Vector3D P1_norm = P1_proj.GetVector3D() / P1_proj.w;
    Vector3D P2_norm = P2_proj.GetVector3D() / P2_proj.w;
    Vector3D P3_norm = P3_proj.GetVector3D() / P3_proj.w;
    char *P1_norm_str = P1_norm.GetString();
    char *P2_norm_str = P2_norm.GetString();
    char *P3_norm_str = P3_norm.GetString();
    sreMessage(SRE_MESSAGE_LOG, "CalculateProjectionShadowMapMatrix: Point transformations "
        "%s, %s and %s.", P1_norm_str, P2_norm_str, P3_norm_str);
    delete P1_norm_str;
    delete P2_norm_str;
    delete P3_norm_str;
#endif
}
Exemple #27
0
bool Plane::Contains(const Circle &circle, float epsilon) const
{
	return Contains(circle.pos, epsilon) && (EqualAbs(Abs(Dot(normal, circle.normal)), 1.f) || circle.r <= epsilon);
}
Exemple #28
0
/* Determine the polygon normal and project vertices onto the plane
* of the polygon.
*/
void tessProjectPolygon( TESStesselator *tess )
{
	TESSvertex *v, *vHead = &tess->mesh->vHead;
	TESSreal norm[3];
	TESSreal *sUnit, *tUnit;
	int i, first, computedNormal = FALSE;

	norm[0] = tess->normal[0];
	norm[1] = tess->normal[1];
	norm[2] = tess->normal[2];
	if( norm[0] == 0 && norm[1] == 0 && norm[2] == 0 ) {
		ComputeNormal( tess, norm );
		computedNormal = TRUE;
	}
	sUnit = tess->sUnit;
	tUnit = tess->tUnit;
	i = LongAxis( norm );

#if defined(FOR_TRITE_TEST_PROGRAM) || defined(TRUE_PROJECT)
	/* Choose the initial sUnit vector to be approximately perpendicular
	* to the normal.
	*/
	Normalize( norm );

	sUnit[i] = 0;
	sUnit[(i+1)%3] = S_UNIT_X;
	sUnit[(i+2)%3] = S_UNIT_Y;

	/* Now make it exactly perpendicular */
	w = Dot( sUnit, norm );
	sUnit[0] -= w * norm[0];
	sUnit[1] -= w * norm[1];
	sUnit[2] -= w * norm[2];
	Normalize( sUnit );

	/* Choose tUnit so that (sUnit,tUnit,norm) form a right-handed frame */
	tUnit[0] = norm[1]*sUnit[2] - norm[2]*sUnit[1];
	tUnit[1] = norm[2]*sUnit[0] - norm[0]*sUnit[2];
	tUnit[2] = norm[0]*sUnit[1] - norm[1]*sUnit[0];
	Normalize( tUnit );
#else
	/* Project perpendicular to a coordinate axis -- better numerically */
	sUnit[i] = 0;
	sUnit[(i+1)%3] = S_UNIT_X;
	sUnit[(i+2)%3] = S_UNIT_Y;

	tUnit[i] = 0;
	tUnit[(i+1)%3] = (norm[i] > 0) ? -S_UNIT_Y : S_UNIT_Y;
	tUnit[(i+2)%3] = (norm[i] > 0) ? S_UNIT_X : -S_UNIT_X;
#endif

	/* Project the vertices onto the sweep plane */
	for( v = vHead->next; v != vHead; v = v->next )
	{
		v->s = Dot( v->coords, sUnit );
		v->t = Dot( v->coords, tUnit );
	}
	if( computedNormal ) {
		CheckOrientation( tess );
	}

	/* Compute ST bounds. */
	first = 1;
	for( v = vHead->next; v != vHead; v = v->next )
	{
		if (first)
		{
			tess->bmin[0] = tess->bmax[0] = v->s;
			tess->bmin[1] = tess->bmax[1] = v->t;
			first = 0;
		}
		else
		{
			if (v->s < tess->bmin[0]) tess->bmin[0] = v->s;
			if (v->s > tess->bmax[0]) tess->bmax[0] = v->s;
			if (v->t < tess->bmin[1]) tess->bmin[1] = v->t;
			if (v->t > tess->bmax[1]) tess->bmax[1] = v->t;
		}
	}
}
Exemple #29
0
const float Vector4f::Dot(const Vector4 &a) const
{
	return Dot(*this, a);
}
Exemple #30
0
Quaternion Quaternion::Normalize(const Quaternion& q) {
	return q / sqrtf(Dot(q, q));
}