Example #1
0
    void Stroker::handleArcSegment(Segment* segment)
    {
        // Where are we going to?
        updateCurrentPoint(segment->getSegment());

        // First point is already added
        float* points = segment->beginPointIteration();

        points = segment->getNextPoint();

        // First normal using segment end points
        Vector firstNormal = prevPoint_ - currentPoint_;
        firstNormal.normalize();
        firstNormal *= size_ /2;

        scale_.transform(firstNormal);

        // Calculate first and second normal from points
        Vector secondNormal;
        calculateStrokeNormal(points,normal_);
        calculateStrokeNormal(points + 2,secondNormal);

        // Adjust first normal so it points
        // in the same direction as the second normal
        Winding firstWinding  = determineWinding(firstNormal,normal_);
        Winding secondWinding = determineWinding(normal_,secondNormal);

        if(firstWinding != secondWinding)
            firstNormal.invert();

        // Join segments or begin the first segment
        Vector outer;
        Vector inner;

        if(numSegments_ == 0)
        {
            firstPoint_  = prevPoint_;
            firstNormal_ = firstNormal;

            outer = firstPoint_ + firstNormal_;
            inner = firstPoint_ - firstNormal_;

            addPoint(&outerPoints_,outer);
            addPoint(&innerPoints_,inner);
        }
        else
            joiner_(this,prevPoint_,prevNormal_,firstNormal);


        // Add points
        while(segment->hasMorePoints())
        {
            Vector point(*points,*(points + 1));

            calculateStrokeNormal(points,normal_);

            outer = point + normal_;
            inner = point - normal_;

            addPoint(&outerPoints_,outer);
            addPoint(&innerPoints_,inner);

            points = segment->getNextPoint();
        }

        // Add last
        normal_ = invert(firstNormal);

        outer = currentPoint_ + normal_;
        inner = currentPoint_ - normal_;

        addPoint(&outerPoints_,outer);
        addPoint(&innerPoints_,inner);

        prevPoint_  = currentPoint_;
        prevNormal_ = normal_;
    }
Example #2
0
int main(int argc, char** argv){
	CmdLineFind clf( argc, argv );
    int imageWidth  = clf.find( "-NX", 1920, "Image width");
    int imageHeight = clf.find( "-NY", 1080, "Image height");
    double ds = clf.find( "-ds",.1f, "Size of ray march step" );
    string fname = clf.find("-fname","","Name of output file");
    float brightness = clf.find( "-brightness", 1.0f, "Scale brightness of image" );
    float gamma = clf.find( "-gamma", 1.0f, "Gamma of image" );
	int frame =  clf.find( "-frame", 1, "Frame number" );
	
  //  float k = clf.find("-k",1.0f,"Scattering Coefficient");
	vector<float> cPos;
	cPos.push_back(0);
	cPos.push_back(3.0);
	cPos.push_back(-3.0);
	
	cPos = clf.findArray( "-camera", cPos, "Position of the camera");
	
	
	Vector cam( cPos[0], cPos[1], cPos[2] );
	
	Vector dir = -1 * cam;
	dir.normalize();
	
	
	vector<float> Dir;
	Dir.push_back(.75);
	Dir.push_back(-1.25);
	Dir.push_back(1);
	
	Dir = clf.findArray( "-dir", Dir, "look direction");
	
	dir = Vector(Dir[0], Dir[1], Dir[2] );
	dir.normalize();
	
	
	
    Image image;
    image.reset(imageWidth,imageHeight);
    
    Camera camera;
    camera.setEyeViewUp( cam, dir, Vector(0,1,0) );
	camera.setNearPlane(0);
    camera.setFarPlane(10);

    Vector X;
    Vector Xc = camera.eye();
    Vector nHat;
    double sMin = camera.nearPlane();
    double sMax = camera.farPlane();
    Color L;
    double T,dT;
    double alpha;
    double S;



	Volume<float> * Pe,*Ps;
	Volume<Color> * Ce,*Cs;
	
	
//	BaseGrid<float> *grid1 = new SparseGrid<float>();
//	grid1->init(Vector(-7,-4,-4),700,400,400,Vector(7,4,4),0.0);	
	BaseGrid<Vector> *Ugrid = new SparseGrid<Vector>();
	Ugrid->init(Vector(-1,-5,-5),250,250,250,Vector(9,5,5),Vector(0,0,0));
		
	//Ps = new GridVolume<float>(grid1);

	/*
	Noise_t param1;
	//	part.nbWisps() = 1000000;
	//	part.pscale() = 2.5;
	param1.roughness   = 0.9;
	param1.octaves   = 3; 
	param1.fjump     = 2;
	//	param1.wavelength      = 5;
	param1.translate = Vector(1,1,1);
	
	Noise_t param2;
	param2.octaves   = 2; 
	param2.fjump     = 1;
	param2.wavelength      = 2;
	param2.translate = Vector(-2,1,-1);	
	
	Noise_t param3;
	param3.octaves   = 2; 
	param3.fjump     = 2;
	param3.wavelength      = 2;
	param3.translate = Vector(4,-2,1);	
	
	FractalSum<PerlinNoise> *fs1 = new FractalSum<PerlinNoise>();
	fs1->setParameters(param1);
	
	FractalSum<PerlinNoise> *fs2 = new FractalSum<PerlinNoise>();
	fs2->setParameters(param2);
	
	
	FractalSum<PerlinNoise> *fs3 = new FractalSum<PerlinNoise>();
	fs3->setParameters(param3);
	Volume<Vector> *U = new FractalPNVField(fs1,fs2,fs3);
	U = new Curl(U);

	float time = clf.find( "-time", 0.0f, "time of bunny Advection" );
	//ztime += 0.05;
	Volume<float> *dt = new emptyField<float>(time);
	
	U = new Selma(Ugrid,U,dt,0.05);
	*/
	
	
	//Ps = new GridVolume(grid1);
	
//	Ps = new ImplicitSphere(2);
//	Ps = new TranslateScalarField(Ps,Vector(-2,0,0));
	
//	Volume<float> *trophy = new SDF("models/cleanteapot.obj");
//	float angle = clf.find( "-angle", 1.0f, "angle of trophy" );
//	trophy = new RotateScalarField(trophy,Vector(0,-1,0),angle);

	Vector trophyPos(0,5,0);
	Color  trophyColor(212/187.5,175/187.5,55/187.5,0.0);
	//trophy  = new TranslateScalarField(trophy,trophyPos);
	
//	BaseGrid<float> *trophyGrid = new SparseGrid<float>();
	//trophyGrid->init(Vector(-2,-2,-2),200,200,200,Vector(2,2,2),0.0);
	//trophyGrid->sample(trophy);
	//readGrid(trophyGrid,"raw/cleanteapot200.raw");
	//trophy = new GridVolume<float>(trophyGrid);
	 
		
	
	
	
	
/*	Volume<float> *eggy; //   = new ImplicitSphere(2);
	buildEggRobot(&eggy,NULL);
	
	eggy =  new ScaleScalarField(eggy,.3);
	eggy = new RotateScalarField(eggy,Vector(1,0,0),M_PI/2);
	eggy = new RotateScalarField(eggy,Vector(0,0,1),M_PI/2);
	eggy = new RotateScalarField(eggy,Vector(-1,0,0),M_PI/2);
    

	BaseGrid<float> *eggyGrid = new SparseGrid<float>();
	float eggH = clf.find( "-eggH", 0.0f, "Height of Eggy" );
	eggyGrid->init(Vector(-4,-4,-4),400,400,400,Vector(4,4,4),0.0);
	eggyGrid->sample(eggy);
	//readGrid(eggyGrid,"/home/zwelch/819/ZWELCH_819/renderer/raw/hw5Humanoid.raw");
	eggy = new GridVolume<float>(eggyGrid);
	float angle = clf.find( "-angle", 1.0f, "angle of trophy" );
	eggy = new TranslateScalarField(eggy,Vector(-5,eggH,0));
	//Ps = eggy;
	*/

	
	Volume<float> *bunny;//  = new ImplicitSphere(2);
//	bunny = new SDF("models/cleanbunny.obj");
	BaseGrid<float> *bunnyGrid = new SparseGrid<float>();
	bunnyGrid->init(Vector(-1,-2,-5),300,300,300,Vector(1,0,-3),0.0);
	//bunnyGrid->sample(bunny);
	readGrid(bunnyGrid,"/home/zwelch/819/ZWELCH_819/renderer/raw/bunny2layermasked.raw");
//	readGrid(bunnyGrid,"raw/bunny2layermasked.raw");

	Ps = new GridVolume<float>(bunnyGrid);
	Ps = new RotateScalarField(Ps,Vector(1,0,0),M_PI/2);
	Ps= new RotateScalarField(Ps,Vector(0,0,1),-M_PI/2);
	Ps = new RotateScalarField(Ps,Vector(-1,0,0),M_PI/2);

//	Ps = new Composition(Ps,U);
	float eye = clf.find( "-eye", 1.0f, "red of eyes" );
	//Ps = new emptyField<float>(0.0);//new UnionVolume(eggy,bunny);
	Ps = new MaskVolume(Ps);//,0,1);//,0,1);
//	Ps = new UnionVolume(Ps,eggy);
	Volume<float> *leye = new ImplicitSphere(0.05 * eye);
	leye = new TranslateScalarField(leye,Vector(3.6,-.8,-.35));
	Volume<float> *reye = new ImplicitSphere(0.05 * eye);
	reye = new TranslateScalarField(reye,Vector(3.6,-.8,-.55));

	
	Particle pPart;
	//Part.P() = Vector(1,1,1);
	pPart.lifetime() = 100;
	pPart.pyroAmplitude() = .1;
	pPart.octaves() = 2.5;
	vector<Vector> ppts;
	ppts.push_back(Vector(3,-.8,-.325));
	ppts.push_back(Vector(0, 0,0));
	
	PyroTrail ptrail(ppts,271,315,frame,pPart,50);
	
	BaseGrid<float> *LASERGRID = new SparseGrid<float>();
	LASERGRID->init(Vector(-2,-2,-2),300,200,200,Vector(6,2,2),0.0);
	ptrail.stamp(LASERGRID);
	Volume<float>* LASER = new GridVolume<float>(LASERGRID);
	//bunnyGrid->sample(bunny);
	//	readGrid(bunnyGrid,"/home/zwelch/819/ZWELCH_819/renderer/raw/bunny2layermasked.raw");

	
	
	
	
	Pe = new emptyField<float>(0.0);
	Pe = new UnionVolume(leye,reye);
	
	Pe = new MaskVolume(Pe);//,0,1);
	Pe = new UnionVolume(Pe,LASER);
	Cs = new SolidColorField(Color(0.9,.9,0.9,1));//CGridVolume(cgrid);
	Ce = new emptyField<Color>(Color(eye,0,0,1));
	
	
	Volume<float> *k = new kField(15);
	Volume<float> *holdout = new emptyField<float>(0);

	
	DSMgroup DSMs(k);
	BaseGrid<float> *keyDgrid = new SparseGrid<float>();
	keyDgrid->init(Vector(-10,-10,-10),200,200,200,Vector(10,10,10),0.0);
	DSM *key = new DSM(keyDgrid,Ps,ds);
	key->sample(new Light(Vector(10,10,0),Color(1,1,1,1)));
	DSMs.add(key);
	BaseGrid<float> *fillDgrid = new SparseGrid<float>();
	fillDgrid->init(Vector(-10,-10,-10),200,200,200,Vector(10,10,10),0.0);
	DSM *fill = new DSM(fillDgrid,Ps,ds);
	fill->sample(new Light(Vector(0,-10,0),Color(2/3.0,2.0/3,2.0/3,1)));
	DSMs.add(fill);
	BaseGrid<float> *trophyLGrid = new SparseGrid<float>();
	trophyLGrid->init(Vector(-10,-10,-10),250,250,250,Vector(10,10,10),0.0);
	DSM *trophyL = new DSM(trophyLGrid,Ps,ds);
	trophyL->sample(new Light(trophyPos,trophyColor));
	DSMs.add(trophyL);

	
	
	
	clf.usage("-h");
	clf.printFinds();  
	ProgressMeter meter(imageWidth,"render");
	float Pscatter,Pemmit, P;
	for(int i = 0;i < imageWidth; i ++){
        for(int j = 0; j < imageHeight; j++){
            
            nHat = camera.view((double)(i)/(imageWidth-1),(double)(j)/(imageHeight-1));
            X = Xc + nHat * sMin;
            L.set(0.0,0.0,0.0,0.0);
            T = 1;
            S = sMin;
            //raymarch
            while(S < sMax && T >1.0e-6){
                X += nHat * ds;
				if(holdout->eval(X) > 0)
					break;
				Pscatter = Ps->eval(X);
				Pemmit   = Pe->eval(X);
				P = Pscatter + Pemmit;
				

			
				dT = exp (-1.0 * k->eval(X) * ds * P);
				if(P>0){
					L += T * (1-dT) * (Pemmit * Ce->eval(X) + Pscatter * Cs->eval(X) * DSMs.illuminate(X))/P ; 

				}
				//L += Cd->eval(X) * T *(1-dT);
				T *= dT;
				S += ds;
			//	printf("HERE %d\n",__LINE__);
            }
            //after march
            alpha = 1-T;
			
		
			L += Color(0.0,0.0,0.0,alpha);
            image.set(i,j,L);
			
        }
        meter.update();
    }

#ifndef MAGICK
    writeOIIOImage(fname.c_str(),image,brightness,gamma);
#else
    writeMagickImage( clf, image );
#endif
    printf("\a");
    return 0;
    
}
Example #3
0
	// compute polygon list of edge plane intersections
	//
	// This is never called externally and could be private.
	//
	// The representation returned is not efficient, but it appears a
	// typical rendering only contains about 1k triangles.
	void TextureBrick::compute_polygons(Ray& view,
		double tmin, double tmax, double dt,
		vector<float>& vertex, vector<uint32_t>& index,
		vector<uint32_t>& size)
	{
		if (dt <= 0.0)
			return;

		Vector vv[12], tt[12]; // temp storage for vertices and texcoords

		uint32_t degree = 0;

		// find up and right vectors
		Vector vdir = view.direction();
		view_vector_ = vdir;
		Vector up;
		Vector right;
		switch (MinIndex(fabs(vdir.x()),
			fabs(vdir.y()),
			fabs(vdir.z())))
		{
		case 0:
			up.x(0.0); up.y(-vdir.z()); up.z(vdir.y());
			break;
		case 1:
			up.x(-vdir.z()); up.y(0.0); up.z(vdir.x());
			break;
		case 2:
			up.x(-vdir.y()); up.y(vdir.x()); up.z(0.0);
			break;
		}
		up.normalize();
		right = Cross(vdir, up);
		bool order = TextureRenderer::get_update_order();
		size_t vert_count = 0;
		for (double t = order ? tmin : tmax;
		order ? (t < tmax) : (t > tmin);
			t += order ? dt : -dt)
		{
			// we compute polys back to front
			// find intersections
			degree = 0;
			for (size_t j = 0; j < 12; j++)
			{
				double u;

				FLIVR::Vector vec = -view.direction();
				FLIVR::Point pnt = view.parameter(t);
				bool intersects = edge_[j].planeIntersectParameter
					(vec, pnt, u);
				if (intersects && u >= 0.0 && u <= 1.0)
				{
					Point p;
					p = edge_[j].parameter(u);
					vv[degree] = (Vector)p;
					p = tex_edge_[j].parameter(u);
					tt[degree] = (Vector)p;
					degree++;
				}
			}

			if (degree < 3 || degree >6) continue;
			bool sorted = degree > 3;
			uint32_t idx[6];
			if (sorted) {
				// compute centroids
				Vector vc(0.0, 0.0, 0.0), tc(0.0, 0.0, 0.0);
				for (int j = 0; j < degree; j++)
				{
					vc += vv[j]; tc += tt[j];
				}
				vc /= (double)degree; tc /= (double)degree;

				// sort vertices
				double pa[6];
				for (uint32_t i = 0; i < degree; i++)
				{
					double vx = Dot(vv[i] - vc, right);
					double vy = Dot(vv[i] - vc, up);

					// compute pseudo-angle
					pa[i] = vy / (fabs(vx) + fabs(vy));
					if (vx < 0.0) pa[i] = 2.0 - pa[i];
					else if (vy < 0.0) pa[i] = 4.0 + pa[i];
					// init idx
					idx[i] = i;
				}
				Sort(pa, idx, degree);
			}
			// save all of the indices
			for (uint32_t j = 1; j < degree - 1; j++) {
				index.push_back(vert_count);
				index.push_back(vert_count + j);
				index.push_back(vert_count + j + 1);
			}
			// save all of the verts
			for (uint32_t j = 0; j < degree; j++)
			{
				vertex.push_back((sorted ? vv[idx[j]] : vv[j]).x());
				vertex.push_back((sorted ? vv[idx[j]] : vv[j]).y());
				vertex.push_back((sorted ? vv[idx[j]] : vv[j]).z());
				vertex.push_back((sorted ? tt[idx[j]] : tt[j]).x());
				vertex.push_back((sorted ? tt[idx[j]] : tt[j]).y());
				vertex.push_back((sorted ? tt[idx[j]] : tt[j]).z());
				vert_count++;
			}

			size.push_back(degree);
		}
	}
Example #4
0
Vector FlipPath::get_normal(){
    Vector norm =prod * Matrix::rotateXYZ(cur_rotate)* Vector(0,1,0);
    norm.normalize();
    return norm;
}
Example #5
0
void Virus::update() {
  double maxSpeed = 0.2;
  double maxAccel = 0.1;

  switch (virusData->getBodyType()) {
  case VIRUS_BODYTYPE_WORM:
    maxSpeed = virusData->getMovementSpeed();
    maxAccel = 0.012;
    if (gotDestination && state == VIRUSSTATE_MOVING) {
      Vector direction = Vector(position, destination);
      direction = direction.normalize();

      double angle = atan2(direction.y, direction.x) - atan2(0.0, 1.0);
      angle = angle * 180.0 / M_PI;

      double turnSpeed = 0.0;
      double turnTo = angle;
      double distanceAdd;
      double distanceSub;
      if (orientation < turnTo) {
	distanceAdd = turnTo - orientation;
	distanceSub = turnTo + 360.0 - orientation;
      } else {
	distanceAdd = turnTo + 360.0 - orientation;
	distanceSub = orientation - turnTo;
      }

      double distance = std::min(distanceAdd, distanceSub);
      
      if (fabs(distance) > 50.0) {
	turnSpeed = 10.0;
      } else if (fabs(distance) > 10.0) {
	turnSpeed = 5.0;
      } else if (fabs(distance) > 5.0) {
	turnSpeed = 2.5;
      } else if (fabs(distance) > 1.0) {
	turnSpeed = 1.0;
      } else {
	turnSpeed = 0.0;
      }
      
      if (distanceSub < distanceAdd) {
	orientation -= turnSpeed;
      } else {
	orientation += turnSpeed;
      }
      
      if (orientation >= 360.0) {
	orientation -= 360.0;
      }
    }
    break;

  case VIRUS_BODYTYPE_AMOEBA:
    maxSpeed = virusData->getMovementSpeed();
    maxAccel = 0.008;
    orientation += (rotateSpeed / 2.0);
    if (orientation >= 360.0) {
      orientation -= 360.0;
    }
    break;

  case VIRUS_BODYTYPE_SPHERE:
    maxSpeed = virusData->getMovementSpeed();
    maxAccel = 0.2;
    orientation += rotateSpeed;
    if (orientation >= 360.0) {
      orientation -= 360.0;
    }
    break;
  }

  frame++;

  // Virus being cloned inside cell
  if (state == VIRUSSTATE_INACTIVE) {
    Vector speed = Vector(position, destination);
    if (speed.length() > getBoundingCircle().getRadius() / 5.0) {
      speed = speed.normalize();
      speed = speed.mult(0.1);
      position = position.translate(speed);
    }
    return;
  }

  // Virus entering cell
  if (state == VIRUSSTATE_TAKINGCELL) {
    Vector speed = Vector(position, destination);
    if (speed.length() > getBoundingCircle().getRadius() / 5.0) {
      speed = speed.normalize();
      speed = speed.mult(0.05);
      position = position.translate(speed);
    } else {
      dead = true;
      takenCell->startCloning(owner, id);
    }
    return;
  }

  // Virus moving
  if (state == VIRUSSTATE_MOVING) {
    if (!gotDestination) {
      getDestination();
    } else if (reachedDestination()) {
      if (!moveDelay) {
	currentPath.pop_front();
	if (!currentPath.empty()) {
	  getDestination();
	} else {
	  gotDestination = false;
	  state = VIRUSSTATE_IDLE;
	}
      } else {
	gotDestination = false;
	destination = position;
      }
    }
  }

  Vector accel = Vector(0.0, 0.0, 0.0);
  if (gotDestination) {
    accel = Vector(position, destination);
    accel = accel.normalize();
    accel = accel.mult(maxAccel);
  } else {
    speed = Vector(0.0, 0.0, 0.0);
  }

  if (timeOnDestination) {
    double t = (double)timeOnDestination / 60.0;
    maxSpeed *= (0.5) * (1.0 - t);
  }
  speed = speed.translate(accel);
  if (speed.length() > maxSpeed) {
    speed = speed.normalize();
    speed = speed.mult(maxSpeed);
  }

  setPosition(position.translate(speed));

  if (moveDelay) {
    moveDelay--;
  }
  if (attackCooldown) {
    attackCooldown--;
  }
  if (flash) {
    flash--;
  }
  if (reproduceCooldown) {
    reproduceCooldown--;
  }
}
Example #6
0
	void addVertexStates(PotentialVertex *potential, CMSModel3D &input, Vector &vert)
	{
		PotentialVertexState state;
		Vector offset;

		//IN_IN_IN
		if(potential->volumes[IN_IN_IN] != NULL)
		{
			offset =
				(potential->edgeDirections[SET1IN]) +
				(potential->edgeDirections[SET2IN]) +
				(potential->edgeDirections[SET3IN]);
			offset.normalize();
			state.volumes[IN_IN_IN] =
				vertexInsideModel(input, vert + (offset * 0.10f), offset) ? INTERIOR:EXTERIOR;
		}
		else
			state.volumes[IN_IN_IN] = EXTERIOR;
		//IN_IN_OUT
		if(potential->volumes[IN_IN_OUT] != NULL)
		{
			offset =
				(potential->edgeDirections[SET1IN]) +
				(potential->edgeDirections[SET2IN]) +
				(potential->edgeDirections[SET3OUT]);
			offset.normalize();
			state.volumes[IN_IN_OUT] =
				vertexInsideModel(input, vert + (offset * 0.10f), offset) ? INTERIOR:EXTERIOR;
		}
		else
			state.volumes[IN_IN_OUT] = EXTERIOR;
		//IN_OUT_IN
		if(potential->volumes[IN_OUT_IN] != NULL)
		{
			offset =
				(potential->edgeDirections[SET1IN]) +
				(potential->edgeDirections[SET2OUT]) +
				(potential->edgeDirections[SET3IN]);
			offset.normalize();
			state.volumes[IN_OUT_IN] =
				vertexInsideModel(input, vert + (offset * 0.10f), offset) ? INTERIOR:EXTERIOR;
		}
		else
			state.volumes[IN_OUT_IN] = EXTERIOR;
		//IN_OUT_OUT 
		if(potential->volumes[IN_OUT_OUT] != NULL)
		{
			offset =
				(potential->edgeDirections[SET1IN]) +
				(potential->edgeDirections[SET2OUT]) +
				(potential->edgeDirections[SET3OUT]);
			offset.normalize();
			state.volumes[IN_OUT_OUT] =
				vertexInsideModel(input, vert + (offset * 0.10f), offset) ? INTERIOR:EXTERIOR;
		}
		else
			state.volumes[IN_OUT_OUT] = EXTERIOR;
		//OUT_IN_IN
		if(potential->volumes[OUT_IN_IN] != NULL)
		{
			offset =
				(potential->edgeDirections[SET1OUT]) +
				(potential->edgeDirections[SET2IN]) +
				(potential->edgeDirections[SET3IN]);
			offset.normalize();
			state.volumes[OUT_IN_IN] =
				vertexInsideModel(input, vert + (offset * 0.10f), offset) ? INTERIOR:EXTERIOR;
		}
		else
			state.volumes[OUT_IN_IN] = EXTERIOR;
		//OUT_IN_OUT
		if(potential->volumes[OUT_IN_OUT] != NULL)
		{
			offset =
				(potential->edgeDirections[SET1OUT]) +
				(potential->edgeDirections[SET2IN]) +
				(potential->edgeDirections[SET3OUT]);
			offset.normalize();
			state.volumes[OUT_IN_OUT] =
				vertexInsideModel(input, vert + (offset * 0.10f), offset) ? INTERIOR:EXTERIOR;
		}
		else
			state.volumes[OUT_IN_OUT] = EXTERIOR;
		//OUT_OUT_IN
		if(potential->volumes[OUT_OUT_IN] != NULL)
		{
			offset =
				(potential->edgeDirections[SET1OUT]) +
				(potential->edgeDirections[SET2OUT]) +
				(potential->edgeDirections[SET3IN]);
			offset.normalize();
			state.volumes[OUT_OUT_IN] =
				vertexInsideModel(input, vert + (offset * 0.10f), offset) ? INTERIOR:EXTERIOR;
		}
		else
			state.volumes[OUT_OUT_IN] = EXTERIOR;
		//OUT_OUT_OUT
		if(potential->volumes[OUT_OUT_OUT] != NULL)
		{
			offset =
				(potential->edgeDirections[SET1OUT]) +
				(potential->edgeDirections[SET2OUT]) +
				(potential->edgeDirections[SET3OUT]);
			offset.normalize();
			state.volumes[OUT_OUT_OUT] =
				vertexInsideModel(input, vert + (offset * 0.10f), offset) ? INTERIOR:EXTERIOR;
		}
		else
			state.volumes[OUT_OUT_OUT] = EXTERIOR;

		//push state
		potential->states.push_back(state);
	}
Example #7
0
Vector Vector::projection(const Vector& o) const
{
	Vector unit = o.normalize();

	return (*this * o)/o.size()*unit;
}
Example #8
0
Vector Triangle::getNormalAtPoint(Vector& p) {
	Vector v = (p3-p1).cross(p2-p1);
	v.normalize();
	return v;
} 
Example #9
0
GltShape *
MeshSweep(const GltPath3D &f,const double radius,const int slices,const int stacks,const bool convex)
{
    Vector position, prev_position;
    Vector orientation, prev_orientation;
    Vector accel;
    Vector r;

    vector<Vector> vertex(slices);
    vector<Vector> prev_vertex(slices);

    Mesh *mesh = new Mesh();

    GltShapes *meshes = NULL;

    if (convex)
    {
        meshes = new GltShapes();
        meshes->push_back(mesh);
    }

    int pos,vert;

    for (pos=-1;pos<=stacks;pos++)
    {
        // Get position and orientation

        position    = f.f((double) pos / stacks);
        orientation = f.df((double) pos / stacks);
        accel       = f.ddf((double) pos / stacks);

        orientation.normalize();
        accel.normalize();

        // Find a vector in plane normal to orientation

        if (pos==-1)
        {
            if (orientation.x()>orientation.y() && orientation.x()>orientation.z())
                r = xProduct(orientation,VectorY);
            else
            if (orientation.y()>orientation.z())
                r = xProduct(orientation,VectorZ);
            else
                r = xProduct(orientation,VectorX);

            r.normalize();
        }
        else
        {
            double dot = orientation*r;
            double alpha = acos(dot) - M_PI_2;

            Vector axis  = xProduct(orientation,r);
            axis.normalize();
            r = matrixRotate(axis,alpha*M_DEG_PI)*r;
            r.normalize();
        }

        // Calculate vertices around circle

        if (pos>=0)
            for (vert=0;vert<slices;vert++)
            {
                Matrix rotate = matrixRotate(orientation,(double) vert * (360.0/slices));
                vertex[vert] = (rotate*r)*radius+position;
            }

        // Start face

        if (pos==1 || pos>=1 && convex)
        {
            uint32 vBase = mesh->point().size();

            for (vert=0;vert<slices;vert++)
                mesh->point().push_back(Point(prev_vertex[vert],-prev_orientation));

            uint32 vCenter = mesh->point().size();
            mesh->point().push_back(Point(prev_position,-prev_orientation));

            for (vert=0;vert<slices;vert++)
                mesh->triangle().push_back(
                    Triangle(
                        &mesh->point()[vert+vBase],
                        &mesh->point()[((vert+1)%slices)+vBase],
                        &mesh->point()[vCenter]
                    )
                );
        }

        //
        // Connecting segments
        //

        if (pos>=0 && convex || pos==1 && !convex)
            for (vert=0;vert<slices;vert++)
                mesh->point().push_back(Point(prev_vertex[vert],prev_vertex[vert]-prev_position));

        if (pos>=0)
            for (vert=0;vert<slices;vert++)
                mesh->point().push_back(Point(vertex[vert],vertex[vert]-position));

        if (pos>0)
        {
            uint32 vBase = mesh->point().size()-slices;
            uint32 pvBase = vBase-slices;

            for (vert=0;vert<slices;vert++)
            {
                mesh->triangle().push_back(
                    Triangle(
                        &mesh->point()[vert+vBase],
                        &mesh->point()[((vert+1)%slices)+vBase],
                        &mesh->point()[vert+pvBase]
                    )
                );

                mesh->triangle().push_back(
                    Triangle(
                        &mesh->point()[((vert+1)%slices)+vBase],
                        &mesh->point()[((vert+1)%slices)+pvBase],
                        &mesh->point()[vert+pvBase]
                    )
                );
            }

//          #define SWEEP_POV_OUTPUT
            #ifdef SWEEP_POV_OUTPUT

            Vector core = position - prev_position;
            core.normalise();

            double angle = acos(core*VectorX)/Degr;
            Vector axis  = xProduct(core,VectorX);

            Matrix trans = matrixTranslate(prev_position);
            trans = matrixRotate(axis,angle) * trans;
            Matrix inv = trans.inverse();

            double maxx = (inv * prev_vertex[0]).x();
            double minx = (inv * vertex[0]).x();

            for (uint32 v=0;v<stacks;v++)
            {
                double x = (inv * prev_vertex[v]).x();

                maxx = MIN(x,maxx);

                x = (inv * vertex[v]).x();

                minx = MAX(x,minx);
            }

//          cout << minx << ' ' << maxx << endl;

            cout << "cylinder { " << endl;
            (trans * ( VectorX * minx)).writePOV(cout) << ',';
            (trans * ( VectorX * maxx)).writePOV(cout) << ',';
            cout << radius << '}' << endl;
            #endif

        }

        //
        // End face
        //

        if (pos==stacks || pos>=1 && convex)
        {
            uint32 vBase = mesh->point().size();

            for (vert=0;vert<slices;vert++)
                mesh->point().push_back(Point(vertex[vert],orientation));

            uint32 vCenter = mesh->point().size();
            mesh->point().push_back(Point(position,orientation));

            for (vert=0;vert<slices;vert++)
                mesh->triangle().push_back(
                    Triangle(
                        &mesh->point()[((vert+1)%slices)+vBase],
                        &mesh->point()[vert+vBase],
                        &mesh->point()[vCenter]
                    )
                );
        }

        if (pos>0 && pos<stacks && convex)
        {
            mesh = new Mesh();
            meshes->push_back(mesh);
        }

        prev_position = position;
        prev_orientation = orientation;

        swap(vertex,prev_vertex);       // Not efficent way to swap vectors
    }

    if (convex)
        return meshes;

    return mesh;
}
// TimeSlice Interface
void
dmz::StarfighterPluginTargets::update_time_slice (const Float64 TimeDelta) {

   if (_objMod) {

      if (_targetTable.get_count () < _maxTargetCount) {

         Int32 count (0);

         while ((count < 10) && (_targetTable.get_count () < _maxTargetCount)) {

            count++;

            const Handle Target = _objMod->create_object (_targetType, ObjectLocal);

            if (Target) {

               TargetStruct *ts = new TargetStruct (Target);

               if (ts && _targetTable.store (Target, ts)) {

                  ts->start = random_vector (500.0) + _startPos;

                  _objMod->store_position (
                     Target,
                     _defaultObjAttr,
                     ts->start);

                  _objMod->store_orientation (
                     Target,
                     _defaultObjAttr,
                     _startDir);

                  ts->point = random_vector (50.0);

                  ts->distance = (ts->point - ts->start).magnitude ();

                  Vector vel (Forward * _targetSpeed);

                  _startDir.transform_vector (vel);

                  _objMod->store_velocity (Target, _defaultObjAttr, vel);

                  _objMod->activate_object (Target);
               }
               else if (ts) {

                  _objMod->destroy_object (Target);
                  delete ts; ts = 0; 
               }
            }
         }
      }

      HashTableHandleIterator it;
      TargetStruct *ts (0);

      while (_targetTable.get_next (it, ts)) {

         Vector pos, vel;
         Matrix ori;

         _objMod->lookup_position (ts->Object, _defaultObjAttr, pos);
         _objMod->lookup_velocity (ts->Object, _defaultObjAttr, vel);
         _objMod->lookup_orientation (ts->Object, _defaultObjAttr, ori);

         Vector offset (ts->point - pos), targetDir (offset.normalize ()), dir (Forward);

         if (!ts->onTarget) { _new_ori (TimeDelta, targetDir, *ts, ori); }

         if ((pos - ts->start).magnitude () > ts->distance) {

            ts->point = random_vector (500.0);
            ts->start = pos;
            ts->distance = (ts->start - ts->point).magnitude ();
            ts->onTarget = False;
         }

         ori.transform_vector (dir);
         vel = dir * _targetSpeed;
         pos = pos + (vel * TimeDelta);

         _objMod->store_position (ts->Object, _defaultObjAttr, pos);
         _objMod->store_velocity (ts->Object, _defaultObjAttr, vel);
         _objMod->store_orientation (ts->Object, _defaultObjAttr, ori);
      }
   }
}
Example #11
0
Vector Sphere::getNormalAt(Vector position) {
    Vector normal = position - position_;
    normal.normalize();
    return normal;
}
Example #12
0
Color Scene::trace(const Ray &ray, int steps,double eta1)
{
    // Find hit object and distance
    Hit min_hit(std::numeric_limits<double>::infinity(),Vector());
    Object *obj = NULL;
    for (unsigned int i = 0; i < objects.size(); ++i) {
        Hit hit(objects[i]->intersect(ray));
        if (hit.t<min_hit.t) {
            min_hit = hit;
            obj = objects[i];
        }
    }

    // No hit? Return background color.
    if (!obj) return Color(0.0, 0.0, 0.0);

    Material *material = obj->material;            //the hit objects material
    Point hit = ray.at(min_hit.t);                 //the hit point
    Vector N = min_hit.N;                          //the normal at hit point
    Vector V = -ray.D;                             //the view vector

    /****************************************************
    * This is where you should insert the color
    * calculation (Phong model).
    *
    * Given: material, hit, N, V, lights[]
    * Sought: color
    *
    * Hints: (see triple.h)
    *        Triple.dot(Vector) dot product
    *        Vector+Vector      vector sum
    *        Vector-Vector      vector difference
    *        Point-Point        yields vector
    *        Vector.normalize() normalizes vector, returns length
    *        double*Color        scales each color component (r,g,b)
    *        Color*Color        dito
    *        pow(a,b)           a to the power of b
    ****************************************************/

    // extract and/or declare variables
    // for lighting calculations
    Color ambient = Color(1.0,1.0,1.0); // ambient colour
    Color base = material->color; // material colour
    double ka = material->ka; // ambient intensity;
    double kd = material->kd; // diffuse intensity
    double ks = material->ks; // specular intensity
    double e = material->n; // exponent of specular highlight size
    double reflect = material->reflect; // reflect coefficient
    double refract = material->refract; // refraction coefficient
    double eta2 = material->eta; // refraction index

    if(eta1 == eta2){
      eta2 = AIR_ETA;
    }

    // get reflected ray
    Vector vec_ref = ray.D - (2.0 *(ray.D.dot(N))*N); // reflect ray direction
    Ray ray_ref(hit,vec_ref); //reflect ray
    // jiggle the ray
    jiggle(ray_ref);

    // hack
    Vector frac_n;
    if(ray.D.dot(N) < 0.0){
      frac_n = N;
    }else{
      frac_n = -N;
    }

    // get refracted ray
    bool frac_flag;
    Vector frac_dir = fractf(eta1,eta2,ray.D,frac_n); // direction of refraction

    Ray ray_frac(hit,frac_dir); // ray going out of the material
    if(frac_dir.length_2() > 0.0 && refract > 0.0){
      frac_flag = true;
    }else{
      frac_flag = false;
    }

    // jiggle the ray
    jiggle(ray_frac);

    Color c_ref; // colour of reflected ray
    Color c_frac; // colour of refracted ray
    // recursively trace reflected/refracted rays up to steps times
    if(steps > 0){
      if(reflect > 0.0) c_ref = trace(ray_ref,steps-1,eta1);
      if(frac_flag) c_frac = trace(ray_frac, steps-1,eta2);
    }

    Color color = ka * base * ambient; // set ambient colour
    for(unsigned int i = 0;i<lights.size();i++){
      bool shaded = false; // flag if the current light cast a shadow
      Vector L = hit - lights[i]->position; // vector of light direction
      Vector SL = lights[i]->position - hit; // vector of shadow feeler
      L.normalize();
      SL.normalize();

      // get shadow feelers
      Ray feeler = Ray(hit,SL);
      //jiggle Ray
      jiggle(feeler);
      // test to see if object is in shadow
      if(shadows){
      for(unsigned int j = 0;j<objects.size();j++){
        Hit test(objects[j]->intersect(feeler));
        if(test.t >= 0.0)  {
          shaded = true;
          break;
        }
      }
    }

      if(!shaded){
        Color lc = lights[i]->color; // colour of light

        double lnDot = L.dot(N); // dot product of light

        Vector R = L - (2.0*N*lnDot); // reflection vector
        R.normalize();
        double rvDot = R.dot(V) ;

        color += (kd*base*lc*max(0.0,lnDot)) + (ks*lc*pow(max(0.0,rvDot),e));
      }
    }

    color += reflect*c_ref + refract*c_frac;

    return color;
}
Example #13
0
void Raytracer::render(const char *filename, const char *depth_filename,
                       Scene const &scene)
{
    // Allocate the two images that will ultimately be saved.
    Image colorImage(scene.resolution[0], scene.resolution[1]);
    Image depthImage(scene.resolution[0], scene.resolution[1]);
    
    // Create the zBuffer.
    double *zBuffer = new double[scene.resolution[0] * scene.resolution[1]];
    for(int i = 0; i < scene.resolution[0] * scene.resolution[1]; i++) {
        zBuffer[i] = DBL_MAX;
    }

	// @@@@@@ YOUR CODE HERE
	// calculate camera parameters for rays, refer to the slides for details
	//!!! USEFUL NOTES: tan() takes rad rather than degree, use deg2rad() to transform
	//!!! USEFUL NOTES: view plane can be anywhere, but it will be implemented differently,
	//you can find references from the course slides 22_GlobalIllum.pdf
    
    
	Vector cameraPos = scene.camera.position;
	Vector cameraCenter = scene.camera.center;
	
	Vector cameraPosR = scene.camera.position;
	Vector cameraCenterR = scene.camera.center;
	
	// viewing direction vector get by taking center and subtracting camera position
	Vector wVecOriginal = scene.camera.center; - cameraPos;
    wVecOriginal.normalize();
	// up vector is defined (u)
    Vector uVec = scene.camera.up;
    uVec.normalize();
	// right vector is gotten by taking the cross product of w and v
	Vector rVecOriginal = wVecOriginal.cross(uVec);
	rVecOriginal.normalize();
	
	double stereoDisplacement = scene.camera.stereoDist / 2.0;
	int widthResolution = scene.resolution[0];
	if (scene.camera.stereoDist > 0.0) {		
		printf("Start left picture.\n");
		cameraPos = scene.camera.position + (rVecOriginal * stereoDisplacement);
		cameraPosR = scene.camera.position - (rVecOriginal * stereoDisplacement);
		
		widthResolution = floor(scene.resolution[0] / 2);
	} else if (scene.camera.stereoDist < 0.0) {		
		printf("Start left picture.\n");
		stereoDisplacement = - scene.camera.stereoDist / 2.0;
		cameraPos = scene.camera.position - (rVecOriginal * stereoDisplacement);
		cameraPosR = scene.camera.position + (rVecOriginal * stereoDisplacement);
		
		widthResolution = floor(scene.resolution[0] / 2);
	}

	
    Vector wVec = cameraCenter - cameraPos;
    wVec.normalize();
    Vector rVec = wVec.cross(uVec);
    rVec.normalize();
    
    // get top from tan(fovy)
    double tangent = tan(deg2rad(scene.camera.fovy/2));
	//double atangent = atan(deg2rad(scene.camera.fovy)/2);
    // get length of top from centre of image plane
    double top = scene.camera.zNear * tangent;
    double right = top * scene.camera.aspect;
	if (scene.camera.stereoDist != 0.0) {		
		right = right / 2;
	}
    double left = -right;
    double bottom = -top;
	
    // calculate vector from camera to left top of image plane
    Vector centerVec = cameraPos + (scene.camera.zNear * wVec);
    Vector oVec = centerVec + (left * rVec) + (bottom * uVec);
    double deltaU = (right - left) / scene.resolution[0];
	if (scene.camera.stereoDist != 0.0) {		
		deltaU = deltaU * 2;
	}
    double deltaV = (top - bottom) / scene.resolution[1];    
	    
    // Iterate over all the pixels in the image.
    for(int y = 0; y < scene.resolution[1]; y++) {
        for(int x = 0; x < widthResolution; x++) {

            // Generate the appropriate ray for this pixel
			Ray ray;
			if (scene.objects.empty())
			{
				//no objects in the scene, then we render the default scene:
				//in the default scene, we assume the view plane is at z = 640 with width and height both 640
				ray = Ray(cameraPos, (Vector(-320, -320, 640) + Vector(x + 0.5, y + 0.5, 0) - cameraPos).normalized());
			}
			else
			{
				// set primary ray using the camera parameters
				//!!! USEFUL NOTES: all world coordinate rays need to have a normalized direction
				
				Vector changeU = (x + 0.5) * deltaU * rVec;
                Vector changeY = (y + 0.5) * deltaV * uVec;
                Vector pixelPos = oVec + changeU + changeY;
                
                Vector rayOfHope = pixelPos - cameraPos;
                rayOfHope.normalize();
                
                ray = Ray(cameraPos, rayOfHope);
                //!!! rays do not have w coordinate constructed properly.
			}

            // Initialize recursive ray depth.
            int rayDepth = 0;
           
            // Our recursive raytrace will compute the color and the z-depth
            Vector color;

            // This should be the maximum depth, corresponding to the far plane.
            // NOTE: This assumes the ray direction is unit-length and the
            // ray origin is at the camera position.
            double depth = scene.camera.zFar;

            // Calculate the pixel value by shooting the ray into the scene
            trace(ray, rayDepth, scene, color, depth);

            // Depth test
            if(depth >= scene.camera.zNear && depth <= scene.camera.zFar && 
                depth < zBuffer[x + y*scene.resolution[0]]) {
                zBuffer[x + y*scene.resolution[0]] = depth;

                // Set the image color (and depth)
                colorImage.setPixel(x, y, color);
                depthImage.setPixel(x, y, (depth-scene.camera.zNear) / 
                                        (scene.camera.zFar-scene.camera.zNear));
            }
        }

		//output step information
		if (y % 100 == 0)
		{
			printf("Row %d pixels finished.\n", y);
		}
    }
	
	if (scene.camera.stereoDist != 0.0) {		
		printf("Start right picture.\n");
		Vector wVecR = cameraCenterR - cameraPosR;
		wVecR.normalize();
		// up vector is defined (u)
		// right vector is gotten by taking the cross product of w and v
		Vector rVecR = wVecR.cross(uVec);
		rVecR.normalize();
		
		// calculate vector from camera to left top of image plane
		Vector centerVecR = cameraPosR + (scene.camera.zNear * wVecR);
		Vector oVecR = centerVecR + (left * rVecR) + (bottom * uVec);
		
		// Iterate over all the pixels in the image.
		for(int y = 0; y < scene.resolution[1]; y++) {
			for(int x = 0; x < (scene.resolution[0] / 2); x++) {

				// Generate the appropriate ray for this pixel
				Ray ray;
				if (scene.objects.empty())
				{
					//no objects in the scene, then we render the default scene:
					//in the default scene, we assume the view plane is at z = 640 with width and height both 640
					ray = Ray(cameraPosR, (Vector(-320, -320, 640) + Vector(x + 0.5, y + 0.5, 0) - cameraPosR).normalized());
				}
				else
				{
					// set primary ray using the camera parameters
					//!!! USEFUL NOTES: all world coordinate rays need to have a normalized direction
					
					Vector changeU = (x + 0.5) * deltaU * rVecR;
					Vector changeY = (y + 0.5) * deltaV * uVec;
					Vector pixelPos = oVecR + changeU + changeY;
					
					Vector rayOfHope = pixelPos - cameraPosR;
					rayOfHope.normalize();
					ray = Ray(cameraPosR, rayOfHope);
					//!!! rays do not have w coordinate constructed properly.
				}

				// Initialize recursive ray depth.
				int rayDepth = 0;
			   
				// Our recursive raytrace will compute the color and the z-depth
				Vector color;

				// This should be the maximum depth, corresponding to the far plane.
				// NOTE: This assumes the ray direction is unit-length and the
				// ray origin is at the camera position.
				double depth = scene.camera.zFar;

				// Calculate the pixel value by shooting the ray into the scene
				trace(ray, rayDepth, scene, color, depth);

				// Depth test
				int testDepth = x + floor(scene.resolution[0] / 2) + y*scene.resolution[0];
				if(depth >= scene.camera.zNear && depth <= scene.camera.zFar && 
					depth < zBuffer[testDepth]) {
					zBuffer[testDepth] = depth;

					// Set the image color (and depth)
					colorImage.setPixel(x+floor(scene.resolution[0] / 2), y, color);
					depthImage.setPixel(x+floor(scene.resolution[0] / 2), y, (depth-scene.camera.zNear) / 
											(scene.camera.zFar-scene.camera.zNear));
				}
			}

			//output step information
			if (y % 100 == 0)
			{
				printf("Row %d pixels finished.\n", y);
			}
		}
	}

	//save image
    colorImage.writeBMP(filename);
    depthImage.writeBMP(depth_filename);

	printf("Ray tracing finished with images saved.\n");

    delete[] zBuffer;
}
Example #14
0
// Calculate sphere normal
Vector Sphere::normal_in (const Point& p)
{
	Vector v ((p.x-center.x)/radius, (p.y-center.y)/radius, (p.z-center.z)/radius);
	v.normalize ();
	return v;
}
Example #15
0
// ----------------------------------------------------- tracePhong ------------------------------------------------------------------ //
Color Scene::tracePhongGooch(const Ray &ray, int recursionDepth){
    // Find hit object and distance
    Hit min_hit(std::numeric_limits<double>::infinity(),Vector());
    Object *obj = NULL;
    for (unsigned int i = 0; i < objects.size(); ++i) {
        Hit hit(objects[i]->intersect(ray));
        if (hit.t<min_hit.t) {
            min_hit = hit;
            obj = objects[i];
        }
    }

    // No hit? Return background color.
    if (!obj) return Color(0.0, 0.0, 0.0);

    Material *material = obj->material;            //the hit objects material
    Point hit = ray.at(min_hit.t);                 //the hit point
    Vector N = min_hit.N;                          //the normal at hit point
    Vector V = -ray.D;                             //the view vector


    /****************************************************
    * This is where you should insert the color
    * calculation (Phong model).
    *
    * Given: material, hit, N, V, lights[]
    * Sought: color
    *
    * Hints: (see triple.h)
    *        Triple.dot(Vector) dot product
    *        Vector+Vector      vector sum
    *        Vector-Vector      vector difference
    *        Point-Point        yields vector
    *        Vector.normalize() normalizes vector, returns length
    *        double*Color        scales each color component (r,g,b)
    *        Color*Color        dito
    *        pow(a,b)           a to the power of b
    ****************************************************/

    Color color;

    //For each light
	for(unsigned int i = 0; i < lights.size(); i++){
		bool isShadow = false;

		if (rendermode == phong) //Ambiant
			color += lights[i]->color * material->color * material->ka;

		//Shadow
		if(Shadow){
			//Ray from light to object
			Ray light(lights[i]->position, hit - lights[i]->position);

			//Hit from light to nearest object
			Hit minHit = findMinHit(light);

			//Hit from current object to light
			Hit currentHit(obj->intersect(light));

			//
			if (minHit.t < currentHit.t) isShadow = true;
		}
		//No Shadow -> Calculate colors
		if(!isShadow){

			//The light vector
			Vector L = lights[i]->position - hit;L.normalize();
			//The R vector (required for specular shading)
			Vector R = (-1*L) + 2 * (L.dot(N)) * N;

			if (rendermode == phong) //Diffuse
				if (material->texture){
					color += (max(0.0,N.dot(L)) * lights[i]->color) * obj->calcTexture(hit) * material->kd;
				} else { 
					color += (max(0.0,N.dot(L)) * lights[i]->color) * material->color * material->kd;
				}
			if (rendermode == gooch && ray.D.dot(N)<-0.2){
				Color kCool = Color(0.0,0.0,kBlue) + alpha * (lights[i]->color * material->color * material->kd);
				Color kWarm = Color(kYellow,kYellow,0.0) + beta * (lights[i]->color * material->color * material->kd);
				color += (kCool *(1 - N.dot(L))/2) + (kWarm * (1 + N.dot(L))/2);
			}

			//Specular		+ dot(R,V)^n LightColor ks
			color += pow(max(0.0,R.dot(V)), material->n) * lights[i]->color * material->ks;
		}
	}

	//Reflection
	if(recursionDepth <= maxRecursionDepth && ray.D.dot(N)<-0.2){
		Color buffer(0.0, 0.0, 0.0);

		//The reflected direction
		Vector reflectV((V + 2*(-N.dot(V))*N));

		for (unsigned int i=0; i<4; i++){

			//The reflected ray
			Ray reflect(hit + 0.001 * N, -reflectV);

			//Calculate reflection through recursion
			buffer += material->ks*tracePhongGooch(reflect, recursionDepth+1);
			reflectV.x += 0.01 * cos(0.5);
			reflectV.y += 0.01 * sin(0.5);
		}

		//Color = average buffer value
		color += buffer/4;
	}

    return color;
}
Example #16
0
 void Sphere::getNormal (const Point& point, Vector &normalAtPoint) const
 {
   normalAtPoint = point.diff(getPosition());
   normalAtPoint.normalize();
 }
Example #17
0
Vector Vector::normalized() const
{
   Vector result = *this;
   result.normalize();
   return result;
}
Example #18
0
void Bird::chill(vector<Bird> birds, vector<Bird> predators, Vector &cohesion, Vector &separation, Vector &alignment, Vector &avoid) {
    int numNeighbors = 0;

    for(auto bird : birds) {
        if(this->isNeighbor(bird)) {

            float dist = this->pos.distance(bird.pos) - this->mass/2 - bird.mass/2;
            if(this->isInSpecies(bird)) {

                // cohesion
                Vector cohesion_force = bird.pos;
                //cohesion_force.mul(1-((dist / this->sight_distance)/2));
                cohesion.add(cohesion_force);
                numNeighbors++;

                // alignment
                if(dist<=this->alignment_radius) {
                    Vector alignment_force = bird.vel;
                    //alignment_force.mul(weightFactor(dist, this->alignment_radius));
                    alignment.add(alignment_force);
                }

                // separation
                if(dist<=this->min_separation) {
                    Vector nearMe = this->pos.diff(bird.pos);
                    //nearMe.mul(1-(dist / this->min_separation));

                    if(nearMe.magnitude()>0) {
                        nearMe = nearMe.normalize();
                        nearMe.div(nearMe.magnitude());
                        separation.add(nearMe);
                    }
                }
            }
            else {
                // avoid another species
                if(dist<=this->species_avoidance_radius) {
                    Vector avoid_force = this->flee(bird);
                    //avoid_force.mul(weightFactor(dist, this->avoidance_radius));
                    avoid.add(avoid_force);
                }
            }
        }
    }

    if(numNeighbors>0) cohesion.div(numNeighbors);

    Vector desired = cohesion.diff(this->pos);
    cohesion = desired;
    cohesion=cohesion.normalize();
    separation=separation.normalize();
    alignment=alignment.normalize();

    // avoid predator
    for(auto predator : predators) {
        if(this->isNeighbor(predator)) {
            float dist = this->pos.distance(predator.pos) - this->mass/2 - predator.mass/2;
            if(dist<=this->predator_avoidance_radius) {
                Vector avoid_force = this->evade(predator);
                //avoid_force.mul(weightFactor(dist, this->avoidance_radius));
                avoid.add(avoid_force);
            }
        }
    }

    avoid=avoid.normalize();
}
Example #19
0
Vector<Type> nNormalize(Vector<Type> v) {
    return v.normalize();
};
void Heightfield::fillProperties(ParsedBlock& pb)
{
    Bitmap* bmp = NULL;
    if (!pb.getBitmapFileProp("file", &bmp, filename)) pb.requiredProp("file");
    W = bmp->getWidth();
    H = bmp->getHeight();
    blur = 0;
    pb.getDoubleProp("blur", &blur);
    heights = new float[W * H];
    float minY = LARGE_FLOAT, maxY = -LARGE_FLOAT;
    // do we have blur? if no, just fetch the source image and store it:
    if (blur <= 0) {
        for (int y = 0; y < H; y++)
            for (int x = 0; x < W; x++) {
                float h = bmp->getPixel(x, y).intensity();
                heights[y * W + x] = h;
                minY = min(minY, h);
                maxY = max(maxY, h);
            }
    } else {
        // We have blur...
        // 1) convert image to greyscale (if not already):
        for (int y = 0; y < H; y++) {
            for (int x = 0; x < W; x++) {
                float f = bmp->getPixel(x, y).intensity();
                bmp->setPixel(x, y, Color(f, f, f));
            }
        }
        // 2) calculate the gaussian coefficients, see http://en.wikipedia.org/wiki/Gaussian_blur
        static float gauss[128][128];
        int R = min(128, nearestInt(float(3 * blur)));
        for (int y = 0; y < R; y++)
            for (int x = 0; x < R; x++)
                gauss[y][x] = float(exp(-(sqr(x) + sqr(y))/(2 * sqr(blur))) / (2 * PI * sqr(blur)));
        // 3) apply gaussian blur with the specified number of blur units:
        // (this is potentially slow for large blur radii)
        for (int y = 0; y < H; y++) {
            for (int x = 0; x < W; x++) {
                float sum = 0;
                for (int dy = -R + 1; dy < R; dy++)
                    for (int dx = -R + 1; dx < R; dx++)
                        sum += gauss[abs(dy)][abs(dx)] * bmp->getPixel(x + dx, y + dy).r;
                heights[y * W + x] = sum;
                minY = min(minY, sum);
                maxY = max(maxY, sum);
            }
        }
    }
    // set the bounding box. minY and maxY are the bbox extents along Y and are calculated
    // from the heights[] array.
    bbox.vmin = Vector(0, minY, 0);
    bbox.vmax = Vector(W, maxY, H);

    // calculate the maxH array. maxH(x, y) = max(H(x, y), H(x + 1, y), H(x, y + 1), H(x + 1, y+1))
    maxH = new float[W*H];
    for (int y = 0; y < H; y++)
        for (int x = 0; x < W; x++) {
            float& maxH = this->maxH[y * W + x];
            maxH = heights[y * W + x];
            if (x < W - 1) maxH = max(maxH, heights[y * W + x + 1]);
            if (y < H - 1) {
                maxH = max(maxH, heights[(y + 1) * W + x]);
                if (x < W - 1)
                    maxH = max(maxH, heights[(y + 1) * W + x + 1]);
            }
        }
    // precalculate the normals at each integer point. We create normals by doing two forward differences
    // on the height along x and y at each point and using the cross product of these differences to
    // obtain the normal vector
    normals = new Vector[W * H];
    for (int y = 0; y < H; y++)
        for (int x = 0; x < W; x++) {
            float h0 = heights[y * W + x];
            float hdx = heights[y * W + min(W - 1, x + 1)];
            float hdy = heights[min(H - 1, y + 1) * W + x];
            Vector vdx = Vector(1, hdx - h0, 0); // forward difference along X
            Vector vdy = Vector(0, hdy - h0, 1); // forward difference along Z
            Vector norm = vdy ^ vdx;
            norm.normalize();
            normals[y * W + x] = norm;
        }
    useOptimization = false;
    pb.getBoolProp("useOptimization", &useOptimization);
    if (!disableAcceleratedStructures && useOptimization) {
        Uint32 clk = SDL_GetTicks();
        buildStruct();
        clk = SDL_GetTicks() - clk;
        printf("Heightfield acceleration struct built in %.3lfs\n", clk / 1000.0);
    }
}
rgb illuminate(Ray ray, Point isect, Vector normal, Vector direction,Object *object, int level)
{

  //  printf("Entering illuminate\n");
  
  rgb c,d;
  
  //do ambient lighting
  c = 0.2 * object->ambient;
  
  int count = lights.size() - 1;



  //diffuse lighting goes here                                                                                                                                                                       


  if (object->image == 1)
    d = charcoal(isect, object);
  
  else if (object->image == 2)
    d = Texture(isect,  object, rgb(.55,.1,.15), rgb(.5,.5,.5));
  
  else if (object->image == 3)
    d = Texture(isect,  object, rgb(0,0,1), rgb(1,1,0));

  else if (object->image == 4)
    d = Texture( isect, object, rgb(.5,0,0), rgb(0.5,0.5,0.5));

  else
    d = object->color;





  //let's loop through the lights
  while (count >= 0)
    {
      //check to see if it's front facing
      Point vvlight;
      Vector vlight;
      double dlight;
                             
      Point tx;
      Vector t;
    

      if (lights[count]->type != eDIR)
	{
	  tx = lights[count]->center - isect;
	  t = p2v(tx);
	  dlight = t.magnitude();
	  
	  vlight = p2v(lights[count]->center) - isect;
	  vlight.t = 0;
	  vlight.normalize();
	}
      
      else
	{
	  vlight =  -1.0*lights[count]->dir;
	}


      if (dot(normal, vlight) > 0.0)
	{
	

	  int blocknum = 0;                                                              
	  vector <int> hold;
	  
	  double check = 100000.0;


	  bool shadow = false;
	  double intensity = lights[count]->intensity;
	  	     
	  if (lights[count]->type == eHOOD)
	    {
	      Vector neg = -1*vlight;
	      neg.t = 0;
	      neg.normalize();
	      
	      Vector D = lights[count]->dir;
	      double phi = dot(neg,D);
	      
	      if (phi > lights[count]->theta)
		{
		  double fall = lights[count]->drop_off * 10;
		  intensity = intensity * pow(phi, fall);
		}

	      else
		{
		  intensity = 0;
		}

	    }
	  
	  
	  
	  int count2 = objects.size() - 1;
	  check = dlight;
	  
	  while (count2 >= 0 && shadow == false )
	    {
	      
	      Ray l;
	      l.start = isect + v2p(vlight)*ns ;
	      check  = dlight;
	      l.direction = vlight;
	      
	      blocknum = find_closest(l, check, isect, &objects);
	      
	      
	      if (check < dlight && blocknum != -1)
		if (objects[count2] -> trans > 0.0)
		  intensity *= .5;
		else
		  shadow = true;
	      
		  
	      count2--;
	    }
	  
	  
	  
	  if (!shadow)
	    { 

	      double angle = dot(normal,vlight);
	      c = c + angle*d*intensity*lights[count]->intensity;

	         
	      //specular component
	      double spec = object->shininess*object->shininess * 1000.0;
	      rgb sc = lights[count]->color;

	      Vector e = direction;
	      Vector ray_ = 2.0*dot(vlight,normal)*normal - vlight;
	      double t2 = pow(dot(e,ray_), spec);
	      // rgb temp = t2*lights[count]->intensity*(object->specular);

	      rgb temp = t2*intensity*(object->specular);
	      if (temp.red >= 0.0 && temp.green >=0.0 && temp.blue >= 0.0)
		c = c + temp*(1.0 - object->shininess);
	    }

	  
	}
      count--;
    }
	  
  
  
    if (object->shininess > 0.01 )
    {
      

    
      //printf("entering reflection\n");
      Vector negdir = -1.0*direction;
      negdir.normalize();
      Ray ref;
      ref.direction =  negdir - 2.0*dot(negdir, normal)*normal;// - negdir;
      ref.direction.normalize();
      ref.direction.t = 0.0;
      ref.start = isect ;//+ v2p(negdir) + v2p(ref.direction)*0.01;
      ref.start = ref.start;// * -1;
      ref.start.t = 1.0;
      
      c = c + object->shininess*shade(ref, level+1);
      
    }

   
    
    
    //refraction time
    
    
    if (object->trans > 0)
      {

      double m1 = cmaterial;
      if (cmaterial == air)
	cmaterial = other;
      else
	cmaterial = air;

      double m2 = cmaterial;


      double sqr = dot(normal, direction) * dot(normal, direction);
      double ctheta = sqrt(1.0 - ((m2/m1)*(m2/m1))*(1-sqr));
      Vector refractedRay = (m2/m1)*direction +((m2/m1)*dot(normal,direction) - ctheta)*normal;
      


     
      refractedRay.normalize();

      Ray refract;
      refract.direction = refractedRay;
      refract.start = v2p(isect + -1*ns*refractedRay);
      c = (1.0-object->trans)*c + object->trans*shade(refract, level+1);
    }
  

  //test color for intersections
  //  c = rgb(.4,.4,.4);
  c.red = clamp(0.0,1.0,c.red);
  c.green = clamp(0.0,1.0,c.green);
  c.blue = clamp(0.0,1.0,c.blue);
  return c;
  
}
Example #22
0
void Boonas::doExtrude(QString num, QString filename) // extrudes and writes whilst extruding 
{
	float n = num.toFloat();
	float x, y, z, w;
	int numSides;
	Point* pa;
	Point* pb;
	Point* pc;
	Point pd;
	Point firstPoint;
	Vector va;
	Vector vb;
	Vector vn;
	bool again = true;
	filename.append(".poly");
	QFile* theDestination;
	theDestination = new QFile(filename);
	theDestination -> remove();
	theDestination -> open(QIODevice::ReadWrite | QIODevice::Text);
	QTextStream outStream( theDestination );
	
	do // do this loop while ther is more in orig
	{
		
		cursor = orig -> getCurrent(); // cursor is current
		cursor -> reset();
		
		//change color respectively for each object
		x = cursor -> getX(); 
		y = cursor -> getY();
		z = cursor -> getZ();
		
		if(colorValue != 0)
		{
			delete colorValue;
			colorValue = 0;
		}
		colorValue = new Point(x, y, z);
		
		cursor -> advance();
		
		if(!(orig -> isNotLast()))
		{
			again = false;
		}
		
		// get initial points in order to get unit vectior
		
		x = cursor -> getX(); 
		y = cursor -> getY();
		z = cursor -> getZ();
		
		pa = new Point(x, y, z);
		
		cursor -> advance();
		
		x = cursor -> getX(); 
		y = cursor -> getY();
		z = cursor -> getZ();
		
		pb = new Point(x, y, z);
		
		cursor -> advance();
		
		x = cursor -> getX(); 
		y = cursor -> getY();
		z = cursor -> getZ();
		
		pc = new Point(x, y, z);
		
		va = *pa - *pb;
		vb = *pb - *pc;
		
		vn = cross(va, vb);
		vn.normalize();
		
		//vn = vn * -1.0; // flip it
		
		vn = vn * n;
		// vn is vector!
		
		cursor -> reset(); // reset cursor so 2nd iteration starts from begining
		
		
		// skip color vector
		cursor -> advance();
		
		numSides = 0;
		
		outStream << "newObject" << endl;
		
		// put out color vector
		outStream << colorValue -> x() << " " << colorValue -> y() << " "<< colorValue -> z() << " 1" << endl;
		
		// first iteration, copy orig polygon, count number of sides
		do
		{
			numSides++;
			//qDebug() << "Test results";
			x = cursor -> getX(); // get point
			y = cursor -> getY();
			z = cursor -> getZ();
			w = cursor -> getW();
			
			outStream << x << " " << y << " " << z << " " << w << endl;
			
			cursor -> advance();
		}
		while(cursor -> hasNext()); // run through the points and mult!k
		
		numSides++;
		x = cursor -> getX(); // get point
		y = cursor -> getY();
		z = cursor -> getZ();
		w = cursor -> getW();
		
		outStream << x << " " << y << " " << z << " " << w << endl;
		//numsides is the number of points
		cursor -> reset();
		
		// skip color vector
		cursor -> advance();
		
		// second iteration, copy the top polygon
		outStream << "newObject" << endl;
		
		// put out color vector
		outStream << colorValue -> x() << " " << colorValue -> y() << " "<< colorValue -> z() << " 1" << endl;
		
		// second iteration, copy orig polygon to traversed points, count number of sides
		do
		{
			//qDebug() << "Test results";
			x = cursor -> getX(); // get point
			y = cursor -> getY();
			z = cursor -> getZ();
			w = cursor -> getW();
			
			delete pa;
			pa = new Point(x, y, z);
			pd = *pa + vn;
			outStream << pd.x() << " " << pd.y() << " " << pd.z() << " " << w << endl;
			
			cursor -> advance();
		}
		while(cursor -> hasNext()); // run through the points and mult!k
		
		x = cursor -> getX(); // get point
		y = cursor -> getY();
		z = cursor -> getZ();
		w = cursor -> getW();
		
		delete pa;
		pa = new Point(x, y, z);
		
		pd = *pa + vn;
		
		outStream << pd.x() << " " << pd.y() << " " << pd.z() << " " << w << endl;
		// start next run time for the sides yo
		cursor -> reset();
		
		// skip color vector
		cursor -> advance();
		
		
		for(int i = 0; i < (numSides - 1); i++) // run through this next bit for each side of the polygon except the last side
		{
			cursor -> reset();
			
			// skip color vector
			cursor -> advance();
			
			outStream << "newObject" << endl;
			
			// put out color vector
			outStream << colorValue -> x() << " " << colorValue -> y() << " "<< colorValue -> z() << " 1" << endl;
			
			for(int j = 0; j < i; j++) // advance cursor to get it to desired point
			{
				cursor -> advance();
			}
			
			x = cursor -> getX(); 
			y = cursor -> getY();
			z = cursor -> getZ();
			w = cursor -> getW();
			
			outStream << x << " " << y << " " << z << " " << w << endl; // out put orig point
			
			delete pa;
			pa = new Point(x, y, z);
			pd = *pa + vn;
			
			outStream << pd.x() << " " << pd.y() << " " << pd.z() << " " << w << endl; // out put mod point a
			
			cursor -> advance(); //advance to next point;
			
			x = cursor -> getX(); 
			y = cursor -> getY();
			z = cursor -> getZ();
			w = cursor -> getW();
			
			delete pa;
			pa = new Point(x, y, z);
			pd = *pa + vn;
			
			outStream << pd.x() << " " << pd.y() << " " << pd.z() << " " << w << endl; // out put mod point b

			outStream << x << " " << y << " " << z << " " << w << endl; // out put last point
		}
		// now we only have to deal with the last side
		
		outStream << "newObject" << endl;
		
		// put out color vector
		outStream << colorValue -> x() << " " << colorValue -> y() << " "<< colorValue -> z() << " 1" << endl;
		
		
		cursor -> reset();
		
		// skip color vector
		cursor -> advance();
		
		for(int i = 0; i < numSides; i++)
		{
			cursor -> advance(); // advance cursor to last point;
		}
		
		x = cursor -> getX(); 
		y = cursor -> getY();
		z = cursor -> getZ();
		w = cursor -> getW();
		
		outStream << x << " " << y << " " << z << " " << w << endl; // out put first point
		
		delete pa;
		pa = new Point(x, y, z);
		pd = *pa + vn;
		
		outStream << pd.x() << " " << pd.y() << " " << pd.z() << " " << w << endl; // out put mod point a
		
		cursor -> reset();
		
		// skip color vector
		cursor -> advance();
		
		x = cursor -> getX(); 
		y = cursor -> getY();
		z = cursor -> getZ();
		w = cursor -> getW();
		
		delete pa;
		pa = new Point(x, y, z);
		pd = *pa + vn;
		
		outStream << pd.x() << " " << pd.y() << " " << pd.z() << " " << w << endl; // out put mod point b
		
		outStream << x << " " << y << " " << z << " " << w << endl; // out put last point
		
		orig -> advance(); // advance what were working with
	}
	while(again);
	
	theDestination -> close();
	delete theDestination;
	delete pa;
	delete pb;
	delete pc;
}