예제 #1
0
void FirstPersonPlayerProperty::ProcessMessage(Message * message)
{
	switch(message->type)
	{
		case MessageType::COLLISSION_CALLBACK:
		{
			Time now = Time::Now();
			CollisionCallback * cc = (CollisionCallback*) message;
			// Enable jumping again after impact.
			if (AbsoluteValue(cc->impactNormal.y) > 0.9f)
			{
				/// If was in auto-run, starting running again.
				if ((now - lastJump).Milliseconds() > jumpCooldownMs)
				{
					jumping = false;
					if (autorun)
					{
						assert(movementSpeed == movementSpeed);
						PhysicsQueue.Add(new PMSetEntity(owner, PT_RELATIVE_ACCELERATION, Vector3f(0, 0, movementSpeed)));
					}
				}
			}
			break;	
		}

		case MessageType::RAYCAST:
		{
			if (!this->raycast)
				return;
			Raycast * raycastMessage = (Raycast*) message;
			List<Intersection> contacts = raycastMessage->isecs;
			targets.Clear();

			Ray ray = raycastMessage->ray;
			if (contacts.Size())
			{
				lastRaycastTargetPosition = ray.start + ray.direction * contacts[0].distance;
			}

			/// Move list of contacts to list of entities?
			for (int i = 0; i < contacts.Size(); ++i)
			{
				Intersection & contact = contacts[i];
				Entity * entity = contact.entity;
//				std::cout<<"\n contacts "<<i<<" "<<entity->name;
				targets.Add(entity);
			}
			// Set primary target to the first one from the raycast.
			if (targets.Size())
			{
				primaryTarget = targets[0];
		//		std::cout<<"\nTarget found: "<<targets[0]->name;	
			}
			else
				primaryTarget = NULL;

			break;	
		}
	}
}
예제 #2
0
internal uint32_t GetBestMatchAsset(assets_s* assets, assetType_e typeId, assetVector_s* matchVector, 
    assetVector_s* weightVector)
{
    uint32_t result = 0;
    float bestDiff = FLOAT_MAX;
    waAssetType_s* type = &assets->assetTypes[typeId];
    for(uint32_t assetIndex = type->firstAssetIndex; assetIndex < type->onePastLastAssetIndex; assetIndex++)
    {
        assetFileData_s* asset = &assets->assets[assetIndex];
        float totalWeightedDiff = 0.0f;
        for(uint32_t tagIndex = asset->wa.firstTagIndex; tagIndex < asset->wa.onePastLastTagIndex; tagIndex++)
        {
            waTag_s* tag = &assets->tags[tagIndex];
            float difference = matchVector->e[tag->id] - tag->value;
            float weighted = weightVector->e[tag->id] * AbsoluteValue(difference);
            totalWeightedDiff += weighted;
        }

        if(totalWeightedDiff < bestDiff)
        {
            bestDiff = totalWeightedDiff;
            result = assetIndex;
        }
    }

    return result;
}
예제 #3
0
파일: TextFont.cpp 프로젝트: erenik/engine
/// Returns the size required by a call to RenderText if it were to be done now.
Vector2f TextFont::CalculateRenderSizeUnits(Text & text)
{
	if (text.Length() < 1)
	{
		return Vector2f(scale[0], scale[1]);
	}
	// Set starting variables.
	NewText(text);

	// Go up to and include the NULL-sign!
	for (int i = 0; i < text.ArraySize(); ++i)
	{
		currentCharIndex = i;
		currentChar = text.c_str()[i];
		if (currentChar == '\0')
		{
			EndText();
			break;
		}
		nextChar = text.c_str()[i + 1];
		if (EvaluateSpecialChar())
			continue;
		StartChar();
		// RenderChar();
		EndChar();
		lastChar = currentChar;
	}
	return Vector2f (maxRowSizeX, AbsoluteValue(pivotPoint.y));
}
예제 #4
0
파일: TextFont.cpp 프로젝트: erenik/engine
/// Calculates the render size in pixels if the text were to be rendered now.
Vector2f TextFont::CalculateRenderSizeWorldSpace(Text & text, GraphicsState & graphics)
{
	// Just grab required render size and multiply with the model-matrix?
	Vector2f renderSize = CalculateRenderSizeUnits(text);
	Vector4f size(renderSize[0], renderSize[1], 0, 0);
	Vector4f transformed = graphics.modelMatrixF.Product(size);
	return Vector2f(transformed[0], AbsoluteValue(transformed[1]));
}
예제 #5
0
파일: Mesh.cpp 프로젝트: erenik/engine
/// Searches through the mesh's numVertices and returns the maximum bounding radius required by the Entity.
float getMaxBoundingRadius(Mesh * mesh){
/*	if (mesh == NULL){
		std::cout<<"WARNING: Mesh NULL in getMaxBoundingRadius!";
		return 0;
	}
	*/
	float maxX = 0.0f, maxY = 0.0f, maxZ = 0.0f;
	for (int i = 0; i < mesh->numVertices; ++i){
		if (AbsoluteValue(mesh->vertices[i][0]) > maxX)
			maxX = mesh->vertices[i][0];
		if (AbsoluteValue(mesh->vertices[i][1]) > maxY)
			maxY = mesh->vertices[i][1];
		if (AbsoluteValue(mesh->vertices[i][2]) > maxZ)
			maxZ = mesh->vertices[i][2];
	}
	float max = sqrt(pow(maxX, 2) + pow(maxY, 2) + pow(maxZ, 2));
	return max;
}
예제 #6
0
/******************************************************************************
* Name: ConvertSpeedToDutyCycle
*
* Description: Returns duty cycle corresponding to specified linear speed in cm/sec.
******************************************************************************/
float DCBrushedMotor::ConvertSpeedToDutyCycle
(
    float speed // Must be positive. (cm / sec)
)
{
    float angular_rate = AbsoluteValue(speed) / wheel_circumference * 360.f;
    float duty_cycle = angular_rate / angular_rate_per_duty;

    return duty_cycle;

} // ConvertSpeedToDutyCycle()
예제 #7
0
파일: xtrsv.hpp 프로젝트: gpu/CLBlast
  // Describes how to prepare the input data
  static void PrepareData(const Arguments<T> &args, Queue&, const int, std::vector<T> &x_source,
                          std::vector<T>&, std::vector<T> &a_source, std::vector<T>&, std::vector<T>&,
                          std::vector<T>&, std::vector<T>&) {
    if (args.a_ld < args.n) { return; }
    if (args.a_size <= 0 || args.x_size <= 0) { return; }

    // Generates 'proper' input for the TRSV routine
    // TODO: Improve this, currently loosely based on clBLAS's implementation
    for (auto i = size_t{0}; i < args.n; ++i) {
      auto diagonal = a_source[i*args.a_ld + i + args.a_offset];
      diagonal = static_cast<T>(AbsoluteValue(diagonal)) + static_cast<T>(args.n / size_t{4});
      for (auto j = size_t{0}; j < args.n; ++j) {
        a_source[j*args.a_ld + i + args.a_offset] /= Constant<T>(2.0);
      }
      a_source[i*args.a_ld + i + args.a_offset] = diagonal;
      x_source[i * args.x_inc + args.x_offset] /= Constant<T>(2.0);
    }
  }
예제 #8
0
int CVMergeLines::Process(CVPipeline * pipe)
{
	for (int i = 0; i < pipe->lines.Size(); ++i)
	{
		Line & line1 = pipe->lines[i];
		// Make sure it's normalized.
		Vector3f dir = line1.direction.NormalizedCopy();
		for (int j = 0; j < pipe->lines.Size(); ++j)
		{
			if (i == j)
				continue;

			Line & line2 = pipe->lines[j];	
			// Check that the directions align.
			Vector3f dir2 = line2.direction.NormalizedCopy();

			if (AbsoluteValue(dir.DotProduct(dir2)) < 0.95f)
				continue;
		
			// Check overlap distance. If not overlapping at all, skip 'em.
	//		if (line1.stop.x < line2.start.x ||
		//		line1.start.x > line2.stop.x)
		//		continue;

			// Check the distance between the lines.
			float distance = (line1.start - line2.start).Length();
			if (distance < maxDistance->GetFloat())
			{
				// Merge 'em
				line1.Merge(line2);
				pipe->lines.RemoveIndex(j);
				--j;
			}
		}
	}
	returnType = CVReturnType::LINES;
	return returnType;
}
예제 #9
0
/// If no cloud-system, spawns globally, based on the given boundaries (.
void PrecipitationSystem::SpawnNewGlobal(int timeInMs)
{
	/// Require 20+ fps.
	timeInMs = timeInMs % 50;
	// Try and emit each particles that the emitter wants to emit.
	/// check size of the emitter.
	float area = globalEmitter.SurfaceArea();
	int dropsPerSecond = area * rainAmount;
	int dropsToEmit = dropsPerSecond * timeInMs * 0.001f;

	Vector3f rainSpeed = Vector3f(0,-emissionVelocity,0);
	int seconds = altitude / AbsoluteValue(rainSpeed.y) + 3;

	/// Assume 1 primary global camera.
	Vector3f cameraPosition;
	AppWindow * window = MainWindow();
	if (window)
	{
		Camera * camera = window->MainViewport()->camera;
		if (camera)
		{
			cameraPosition = camera->Position();
		}
	}


	Vector3f cameraOffset = cameraPosition; // + camera->Velocity();
	Vector3f positionOffsetDueToWind = -weather->globalWind * seconds;
	Vector3f allPositionOffsets = cameraOffset + positionOffsetDueToWind + Vector3f(0,altitude,0);
	Vector3f position;
	Vector3f velocity;
	Vector2f pScale;
	float lifeTime;
	Vector4f pColor;

	for (int j = 0; j < dropsToEmit; ++j)
	{
		// Grab free index.
		int freeIndex = aliveParticles;
		// Skip if reaching max.
		if (freeIndex >= this->maxParticles)
		{
//				std::cout<<"\nEmitter unable to spawn particle. Max particles reached.";
			break;
		}
#ifdef SSE_PARTICLES
		// Position based on the global emitter (default an XZ plane.
		globalEmitter.Position(position);
		// Add random from 0 to 1.0 to get some variation in height?
		position.y += rand()*oneDivRandMaxFloat;
		// Add all offsets, such as altitude, camera position and offset due to wind.
		position += allPositionOffsets;
		lifeTime = seconds;
		/// Big rain (5 mm), 9 m/s, drizzle (0.5mm), 2 m/s.
		velocity = rainSpeed;

		/// Copy over data.
		positionsSSE[freeIndex].data = position.data;
		colorsSSE[freeIndex].data = color.data;
		velocitiesSSE[freeIndex].data = rainSpeed.data;
		float floats[4] = {lifeTime , 0, scale.x, scale.y};
		ldsSSE[freeIndex].data = _mm_loadu_ps(floats);
		/*
		ldsSSE[freeIndex].x = lifeTime;
		ldsSSE[freeIndex].y = 0;
		ldsSSE[freeIndex].z = scale.x;
		ldsSSE[freeIndex].w = scale.y;
		*/
		// Increment amount of living particles.
		++aliveParticles;
	
#else // Not SSE_PARTICLES
		Vector3f & position = positions[freeIndex];
		Vector3f & velocity = velocities[freeIndex];
		Vector2f & pScale = scales[freeIndex];
		float & lifeTime = lifeTimes[freeIndex];
		Vector4f & pColor = colors[freeIndex];

		// Position based on the global emitter (default an XZ plane.
		globalEmitter.Position(position);
		// Add random from 0 to 1.0 to get some variation in height?
		position.y += rand()*oneDivRandMaxFloat;
		// Move up position?
		position.y += altitude;
		position += cameraPosition;

		lifeTime = seconds;
		/// Big rain (5 mm), 9 m/s, drizzle (0.5mm), 2 m/s.
		velocity = rainSpeed;
		// Reset duration to 0 to signify that it is newly spawned.
		lifeDurations[freeIndex] = 0;
		// Increment amount of living particles.
		++aliveParticles;
		// Big scale and color for the time being.
		pScale = scale;
		pColor = color;
#endif
	}
}
예제 #10
0
/// Returns false if the colliding entities are no longer in contact after resolution.
bool FirstPersonCR::ResolveCollision(Collision & c)
{
	Entity * dynamic;
	Entity * other;
	if (c.one->physics->type == PhysicsType::DYNAMIC)
	{
		dynamic = c.one;
		other = c.two;
	}
	else 
	{
		dynamic = c.two;
		other = c.one;
	}
	if (c.one->physics->noCollisionResolutions || c.two->physics->noCollisionResolutions)
		return false;

	// Retardation?
//	if (dynamic->physics->lastCollisionMs + dynamic->physics->minCollisionIntervalMs > physicsNowMs)
	//	return false;

	dynamic->physics->lastCollisionMs = physicsNowMs;

	Entity * dynamic2 = (other->physics->type == PhysicsType::DYNAMIC) ? other : NULL;
	Entity * staticEntity;
	Entity * kinematicEntity;
	if (dynamic == c.one)
		other = c.two;
	else
		other = c.one;
	if (!dynamic2)
	{
		staticEntity = other->physics->type == PhysicsType::STATIC? other : NULL;
		kinematicEntity = other->physics->type == PhysicsType::KINEMATIC? other : NULL;
	}
//	std::cout<<"\nCollision: "<<c.one->name<<" "<<c.two->name;
	// Collision..!
	// Static-Dynamic collision.
	if (!dynamic2)
	{
		PhysicsProperty * pp = dynamic->physics;
		// Skip? No.
//		if (kinematicEntity)
//			return true;

		/// Flip normal if dynamic is two.
		if (dynamic == c.two)
			c.collisionNormal *= -1;

		if (c.collisionNormal.y > 0.8f)
			pp->lastGroundCollisionMs = physicsNowMs;

		// Default plane? reflect velocity upward?
		// Reflect based on the normal.
		float velDotNormal = pp->velocity.DotProduct(c.collisionNormal);
		
		/// This will be used to reflect it.
		Vector3f velInNormalDir = c.collisionNormal * velDotNormal;
		Vector3f velInTangent = pp->velocity - velInNormalDir;
		
		Vector3f newVel = velInTangent * (1 - pp->friction) + velInNormalDir * (-pp->restitution);

		/// Apply resitution and stuffs.
		dynamic->physics->velocity = newVel;
		assert(dynamic->parent == 0); 
		/// Adjusting local position may not help if child entity.
		// Old code
		Vector3f moveVec = AbsoluteValue(c.distanceIntoEachOther) * c.collisionNormal;
//		if (moveVec.x || moveVec.z)
//			std::cout<<"\nMoveVec: "<<moveVec;
		dynamic->localPosition += moveVec;
		/// For double-surface collision resolution (not bouncing through walls..)

		/// For the previously backwards-collisions.
//		if (c.distanceIntoEachOther < 0)
	//		dynamic->localPosition += c.distanceIntoEachOther * c.collisionNormal;
//		else // Old code
	//		dynamic->localPosition += AbsoluteValue(c.distanceIntoEachOther) * c.collisionNormal;

		/// If below threshold, sleep it.
		if (dynamic->physics->velocity.Length() < inRestThreshold && c.collisionNormal.y > 0.8f)
		{
			// Sleep eeet.
			dynamic->physics->state |= CollisionState::IN_REST;
			// Nullify velocity.
			dynamic->physics->velocity = Vector3f();
		}
		if (debug == 7)
		{
			std::cout<<"\nCollision resolution: "<<(c.one->name+" "+c.two->name+" ")<<c.collisionNormal<<" onePos"<<c.one->worldPosition<<" twoPos"<<c.two->worldPosition;
		}
	}
	// Dynamic-dynamic collision.
	else 
	{
//		std::cout<<"\nProblem?"	;
		/// Push both apart?
		PhysicsProperty * pp = dynamic->physics, * pp2 = dynamic2->physics;

		/// Flip normal if dynamic is two.
		// See if general velocities align with one or the other? or...
		
//		if (dynamic == c.two)

		;// c.collisionNormal *= -1;

//		std::cout<<"\nNormal: "<<c.collisionNormal;

		// Default plane? reflect velocity upward?		
		/// This will be used to reflect it.
		Vector3f velInNormalDir = c.collisionNormal * pp->velocity.DotProduct(c.collisionNormal);
		Vector3f velInNormalDir2 = c.collisionNormal * pp2->velocity.DotProduct(c.collisionNormal);
		Vector3f velInTangent = pp->velocity - velInNormalDir,
			velInTangent2 = pp2->velocity - velInNormalDir2;
		Vector3f velInTangentTot = velInTangent + velInTangent2,
			velInNormalDirTot = velInNormalDir + velInNormalDir2;		
		/// Use lower value restitution of the two?
		float restitution = 0.5f; // MinimumFloat(pp->restitution, pp2->restitution);
		Vector3f normalDirPart = velInNormalDirTot * restitution * 0.5f;
		Vector3f to2 = (dynamic2->worldPosition - dynamic->worldPosition).NormalizedCopy();
		float partTo2 = normalDirPart.DotProduct(to2);
	//	std::cout<<" normalDirPart: "<<normalDirPart;

		float normalDirPartVal = normalDirPart.Length();

		Vector3f fromCollisionToDyn1 = (dynamic->worldPosition - c.collissionPoint).NormalizedCopy();
		Vector3f fromCollisionToDyn2 = (dynamic2->worldPosition - c.collissionPoint).NormalizedCopy();

		pp->velocity = velInTangent * (1 - pp->friction) + fromCollisionToDyn1 * normalDirPartVal;
		pp2->velocity = velInTangent2 * (1 - pp->friction) + fromCollisionToDyn2 * normalDirPartVal;
		/// Apply resitution and stuffs.
		assert(dynamic->parent == 0);
		/// Adjusting local position may not help if child entity.
		// Old code
		float distanceIntoAbsH = AbsoluteValue(c.distanceIntoEachOther * 0.5f);

		dynamic->localPosition += distanceIntoAbsH * fromCollisionToDyn1;
		dynamic2->localPosition += distanceIntoAbsH * fromCollisionToDyn2;

		/// For double-surface collision resolution (not bouncing through walls..)
		/// If below threshold, sleep it.
		if (dynamic->physics->velocity.Length() < inRestThreshold && c.collisionNormal.y > 0.8f)
		{
			pp->Sleep();
		}
		else
			pp->Activate();
		if (pp2->velocity.Length() < inRestThreshold && c.collisionNormal.y > 0.8f)
		{
			pp2->Sleep();
		}
		else
			pp2->Activate();
		if (debug == 7)
		{
			std::cout<<"\nCollision resolution: "<<(c.one->name+" "+c.two->name+" ")<<c.collisionNormal<<" onePos"<<c.one->worldPosition<<" twoPos"<<c.two->worldPosition;
		}
	}


	// Check collision normal.


	return true;
}
예제 #11
0
/// Time passed in seconds..!
void PongPlayerProperty::Process(int timeInMs)
{
	List<Entity*> entities = MapMan.GetEntities();

	Time now = Time::Now();
	int secondsSinceLastInput = (now - lastUserInput).Seconds();
	if (secondsSinceLastInput < 1)
	{
		StopMovement();
		return;
	}

	bool moved = false;
	Entity * closestBall = 0;
	float closestDistance = 1000000.f;
	/// Check distance to ball. Fetch closest/most dangerous one!
	for (int i = 0; i < entities.Size(); ++i)
	{
		Entity * ball = entities[i];
		if (!ball->physics)
			continue;
		PongBallProperty * pbp = (PongBallProperty*) ball->GetProperty("PongBallProperty");
		if (!pbp)
			continue;
		if (pbp->sleeping)
			continue;

		// Check distance.
		Vector3f ballToPaddle = owner->position - ball->position;
		// Ignore balls going away.
		if (ball->physics->velocity.DotProduct(lookAt) > 0)
			continue;
		float distance = AbsoluteValue(ballToPaddle[0]);
		if (!ball->physics)
			continue;
		if (distance > 500.f)
			continue;
		if (distance < closestDistance)
		{
			closestBall = ball;
			closestDistance = distance;
		}
	}
	if (closestBall)
	{
		/// Ball on the wya here?!
		if (lookAt.DotProduct(closestBall->physics->velocity) < 0)
		{
			// Head towards it!
			Vector3f ballToPaddle = owner->position - closestBall->position;
			Vector3f toMove = -ballToPaddle;
			toMove.Normalize();
			toMove *= aiSpeed;
			toMove[1] += closestBall->physics->velocity[1] * 0.5f;
			toMove[0] = toMove[2] = 0;
			Physics.QueueMessage(new PMSetEntity(owner, PT_VELOCITY, Vector3f(toMove)));
			moved = true;
		}
	}
	if (!moved)
		StopMovement();
	
}
예제 #12
0
int CVFindQuads::Process(CVPipeline * pipe)
{
	pipe->quads.Clear();
	good = false;
	/// Check for ... in pipeline
	if (pipe->corners.size() == 0 &&
		pipe->lines.Size() == 0)
	{
		errorString = "No corners or lines in pipeline.";
		return -1;
	}
	float minimumWidthSquared = minimumWidth->GetInt() * minimumWidth->GetInt();
	// Line-style!
	if (pipe->lines.Size())
	{
		int linesAtStart = pipe->lines.Size();
		std::cout<<"\nLines: "<<linesAtStart;
		
		/// Then try to locate at least 2 lines that are parallel first?
		// Approximate, assume 2 horizontal lines, and pick those two which are extremes (highest and lowest).
		List<Line> singleLines;
		for (int i = 0; i < pipe->lines.Size(); ++i)
		{
			Line line = pipe->lines[i];
			Line line2;
			bool foundPair = false;
			// Compare with list of lines.
			for (int j = 0; j < singleLines.Size(); ++j)
			{
				line2 = singleLines[j];
				// Any suitable? 
				// First check length.
				if (AbsoluteValue(line.Length() - line2.Length()) > maxLengthDiff->GetFloat())
					continue;

				// Ensure both the start and end points are pretty parallel
				if (AbsoluteValue(line.start.x - line2.start.x) > maxCornerXDiff->GetFloat())
					continue;
				if (AbsoluteValue(line.stop.x - line2.stop.x) > maxCornerXDiff->GetFloat())
					continue;

				foundPair = true;
				break;
			}

			if (foundPair)
			{
		// Limit the range in X for both lines so that they work "together" (overlapping)
#define Minimum(a,b) ( (a < b) ? a : b)
#define Maximum(a,b) ( (a > b) ? a : b)
				Line min, max;
				if (line.start.y < line2.start.y){
					min = line;
					max = line2;
				}
				else {
					min = line2;
					max = line;
				}
				min.stop.x = max.stop.x = Minimum(min.stop.x, max.stop.x);
				min.start.x = max.start.x = Maximum(min.start.x, max.start.x);

				// Create rectangle using these two lines! o-o
				Quad quad;
				quad.Set4Points(min.start, min.stop, max.stop, max.start);
				pipe->quads.Add(quad);
				good = true;
			}
			// If not, add this line to the list.
			else
				singleLines.Add(line);
		}
	
	}
	// Use corners if we have any.
	if (pipe->corners.size()){
		// Constraint for now...
		if (pipe->corners.size() != 4){
			errorString = "Skipping. Simple algorithm requires exactly 4 corners.";
			return -1;
		}
		// Look through all corners. Find the top 2 and bottom 2.
		List<cv::Point2f> sortedList, unsortedList;
		for (int i = 0; i < pipe->corners.size(); ++i)
			unsortedList.Add(pipe->corners[i]);
		/// Sort by Y-position.
		while (unsortedList.Size())
		{
			cv::Point2f max = unsortedList[0];
			int maxIndex = 0;
			for (int i = 1; i < unsortedList.Size(); ++i)
			{
				cv::Point2f point = pipe->corners[i];
				if (point.y > max.y){
					max = point;
					maxIndex = i;
				}
			}
			// Add the max to the sortedList and remove it from the list to be sorted.
			sortedList.Add(max);
			unsortedList.RemoveIndex(maxIndex);
			std::cout<<"\nAdded item"<<sortedList.Size()<<": "<<max;
		}
		/// Now, store top and bottom.
		List<cv::Point2f> top, bottom;
		top.Add(sortedList[0]);
		top.Add(sortedList[1]);
		bottom.Add(sortedList[2]);
		bottom.Add(sortedList[3]);
	
	#define ToVec3f(cvVec) (Vector3f(cvVec.x, cvVec.y, 0))
	
		if (top[0].x < top[1].x)
		{
			topLeft = ToVec3f(top[0]);
			topRight = ToVec3f(top[1]);
		}
		else {
			topLeft = ToVec3f(top[1]);
			topRight = ToVec3f(top[0]);
		}
		if (bottom[0].x < bottom[1].x)
		{
			bottomLeft = ToVec3f(bottom[0]);
			bottomRight = ToVec3f(bottom[1]);
		}
		else 
		{
			bottomLeft = ToVec3f(bottom[1]);
			bottomRight = ToVec3f(bottom[0]);
		}

		// Fetch vectors for lines between the top and bottom points.
		// From left to right.
		topLine = Vector2f(topRight.x - topLeft.x, topRight.y - topLeft.y);
		bottomLine = Vector2f(bottomRight.x - bottomLeft.x, bottomRight.y - bottomLeft.y);
	
		// Normalize them before dot-product
		topLine.Normalize();
		bottomLine.Normalize();

		// Check that they are parralel
		float dotProduct = topLine.DotProduct(bottomLine);
		if (AbsoluteValue(dotProduct) < 0.9f)
		{
			errorString = "Bottom and top lines not parralell enough.";
			return -1;
		}

		// Fetch vector between left top and left bottom.
		Vector2f topLeftToBottomLeft(bottomLeft.x - topLeft.x, bottomLeft.y - topLeft.y);

		// Check that it is perpendicular to either top or bottom lines.
		topLeftToBottomLeft.Normalize();
		dotProduct = topLine.DotProduct(topLeftToBottomLeft);
		if (AbsoluteValue(dotProduct) > 0.1f)
		{
			errorString = "Left and top lines not perpendicular enough.";
			return -1;
		}


		// We have a quad if we reach here!
		Quad quad;
		quad.Set4Points(ToVec3f(bottomLeft), ToVec3f(bottomRight), ToVec3f(topRight), ToVec3f(topLeft));
		pipe->quads.Add(quad);
	
		good = true;
	}
	returnType = CVReturnType::QUADS;
	return returnType;
}
예제 #13
0
파일: cdl.c 프로젝트: airhuman/cwf
MagickExport MagickPassFail CdlImage(Image *image,const char *cdl)
{
  char
    progress_message[MaxTextExtent];

  CdlImageParameters_t
    param;

  PixelPacket
    *lut = (PixelPacket *) NULL;

  register long
    i;

  MagickPassFail
    status=MagickPass;

  assert(image != (Image *) NULL);
  assert(image->signature == MagickSignature);
  if (cdl == (char *) NULL)
    return(MagickFail);

  param.redslope=1.0;
  param.redoffset=0.0;
  param.redpower=1.0;
  param.greenslope=1.0;
  param.greenoffset=0.0;
  param.greenpower=1.0;
  param.blueslope=1.0;
  param.blueoffset=0.0;
  param.bluepower=1.0;
  param.saturation=0.0;
  param.lut=(PixelPacket *) NULL;

  (void) sscanf(cdl,
		"%lf%*[,/]%lf%*[,/]%lf%*[:/]%lf%*[,/]%lf%*[,/]%lf%*"
		"[:/]%lf%*[,/]%lf%*[,/]%lf%*[:/]%lf",
		&param.redslope,&param.redoffset,&param.redpower,
		&param.greenslope,&param.greenoffset,&param.greenpower
		,&param.blueslope,&param.blueoffset,&param.bluepower,
		&param.saturation);

  param.redslope=AbsoluteValue(param.redslope);
  param.redpower=AbsoluteValue(param.redpower);
  param.greenslope=AbsoluteValue(param.greenslope);
  param.greenpower=AbsoluteValue(param.greenpower);
  param.blueslope=AbsoluteValue(param.blueslope);
  param.bluepower=AbsoluteValue(param.bluepower);

  FormatString(progress_message,
	       "[%%s] cdl %g/%g/%g/%g/%g/%g/%g/%g/%g/%g image...",
	       param.redslope,param.redoffset,param.redpower,
	       param.greenslope,param.greenoffset,param.greenpower,
	       param.blueslope,param.blueoffset,param.bluepower,
	       param.saturation);

  if (!IsRGBCompatibleColorspace(image->colorspace))
    TransformColorspace(image,RGBColorspace);

  /*
    Build a LUT if it is beneficial to do so.
  */
  if ((MaxMap == MaxRGB) && (image->columns*image->rows > MaxMap*3))
    {
      lut=MagickAllocateMemory(PixelPacket *,(MaxMap+1)*sizeof(PixelPacket));
      if (lut != (PixelPacket *) NULL)
	{
#if (MaxMap > 256) && defined(HAVE_OPENMP)
#  pragma omp parallel for schedule(guided)
#endif
	  for (i=0; i <= (long) MaxMap; i++)
	    {
	      lut[i].red=CdlQuantum((Quantum) i,param.redslope,param.redoffset,
				       param.redpower,param.saturation);
	      lut[i].green=CdlQuantum((Quantum) i,param.greenslope,param.greenoffset,
					 param.greenpower,param.saturation);
	      lut[i].blue=CdlQuantum((Quantum) i,param.blueslope,param.blueoffset,
					param.bluepower,param.saturation);
	    }
	  param.lut=lut;
	}
    }