Esempio n. 1
0
 void ToStruct(JOYSTICK_FEATURE& feature) const
 {
     feature.name = new char[m_name.length() + 1];
     feature.type = m_type;
     switch (m_type)
     {
     case JOYSTICK_FEATURE_TYPE_SCALAR:
         Primitive().ToStruct(feature.scalar.primitive);
         break;
     case JOYSTICK_FEATURE_TYPE_ANALOG_STICK:
         Up().ToStruct(feature.analog_stick.up);
         Down().ToStruct(feature.analog_stick.down);
         Right().ToStruct(feature.analog_stick.right);
         Left().ToStruct(feature.analog_stick.left);
         break;
     case JOYSTICK_FEATURE_TYPE_ACCELEROMETER:
         PositiveX().ToStruct(feature.accelerometer.positive_x);
         PositiveY().ToStruct(feature.accelerometer.positive_y);
         PositiveZ().ToStruct(feature.accelerometer.positive_z);
         break;
     case JOYSTICK_FEATURE_TYPE_MOTOR:
         Primitive().ToStruct(feature.motor.primitive);
         break;
     default:
         break;
     }
     std::strcpy(feature.name, m_name.c_str());
 }
Esempio n. 2
0
void posix_words() {
    Primitive( "getwd", &_getwd );
    Colon( "pwd" ); c("getwd"); c("type"); c("cr"); End();

    Primitive( "(getenv)", &_getenv );
    Primitive( "(setenv)", &_setenv );
    Colon( "getenv" ); c("parse-word"); c("(getenv)"); End();
    Colon( "setenv" ); c("parse-word"); c("parse-word"); c("(setenv)"); End();
    Colon( "printenv" );
          c("parse-word"); c("2dup"); c("type");
          Literal((Cell)'='); c("emit");
          c("(getenv)"); If(); c("type"); Then(); c("cr"); End();

    Primitive( "(system)", &_system );
    Primitive( "(exec)",   &_exec );

    /* mmap() protection */
    Constant( "PROT_EXEC",  (Cell)PROT_EXEC );
    Constant( "PROT_READ",  (Cell)PROT_READ );
    Constant( "PROT_WRITE", (Cell)PROT_WRITE );
    Constant( "PROT_NONE",  (Cell)PROT_NONE );

    /* mmap() Flags */
    Constant( "MAP_FIXED",   (Cell)MAP_FIXED );
    Constant( "MAP_SHARED",  (Cell)MAP_SHARED );
    Constant( "MAP_PRIVATE", (Cell)MAP_PRIVATE );

    Primitive( "mmap", &do_mmap );

    Primitive( "getpid", &_getpid );
    Primitive( "getppid", &_getppid );

    /* Signals for kill */
    Constant( "SIGHUP",    (Cell)SIGHUP );
    Constant( "SIGINT",    (Cell)SIGINT );
    Constant( "SIGQUIT",   (Cell)SIGQUIT );
    Constant( "SIGILL",    (Cell)SIGILL );
    Constant( "SIGTRAP",   (Cell)SIGTRAP );
    Constant( "SIGABRT",   (Cell)SIGABRT );
    Constant( "SIGIOT",    (Cell)SIGIOT );
    Constant( "SIGBUS",    (Cell)SIGBUS );
    Constant( "SIGFPE",    (Cell)SIGFPE );
    Constant( "SIGKILL",   (Cell)SIGKILL );
    Constant( "SIGUSR1",   (Cell)SIGUSR1 );
    Constant( "SIGSEGV",   (Cell)SIGSEGV );
    Constant( "SIGUSR2",   (Cell)SIGUSR2 );
    Constant( "SIGPIPE",   (Cell)SIGPIPE );
    Constant( "SIGALRM",   (Cell)SIGALRM );
    Constant( "SIGTERM",   (Cell)SIGTERM );
    // Constant( "SIGSTKFLT", (Cell)SIGSTKFLT );
    // Constant( "SIGCLD",    (Cell)SIGCLD );
    Constant( "SIGCHLD",   (Cell)SIGCHLD );
    Constant( "SIGCONT",   (Cell)SIGCONT );
    Constant( "SIGSTOP",   (Cell)SIGSTOP );
    Constant( "SIGTSTP",   (Cell)SIGTSTP );

    Primitive( "kill", &_kill );
}
Esempio n. 3
0
/* Handle * and / operators */
Condition* Term(const char** str)
{
	Condition* t;
	Condition* t1;
	Condition* mid;

    t = (Condition*)FCEU_dmalloc(sizeof(Condition));
    if (!t)
        return NULL;

	memset(t, 0, sizeof(Condition));

	if (!Primitive(str, t))
	{
		freeTree(t);
		return 0;
	}

	while (next == '*' || next == '/')
	{
		int op = next == '*' ? OP_MULT : OP_DIV;

		scan(str);

		if (!(t1 = (Condition*)FCEU_dmalloc(sizeof(Condition))))
            return NULL;

		memset(t1, 0, sizeof(Condition));

		if (!Primitive(str, t1))
		{
			freeTree(t);
			freeTree(t1);
			return 0;
		}

		if (!(mid = (Condition*)FCEU_dmalloc(sizeof(Condition))))
            return NULL;

		memset(mid, 0, sizeof(Condition));

		mid->lhs = t;
		mid->rhs = t1;
		mid->op = op;

		t = mid;
	}

	return t;
}
void PopulateEdgelist(EDGELIST *tree) {
	int level;
	POSITION parent, child;
	MOVELIST *childMoves;
	MOVE theMove;
	OPEN_POS_DATA pdata, cdata;
	int resizeCount = 0;
	int resizeLevelCount = 0;

	if(!kLoopy || !gUseOpen)
		level = 0;

	for(parent=0; parent < gNumberOfPositions; parent++) {
		if(GetValueOfPosition(parent) == undecided &&
		   Remoteness(parent) != REMOTENESS_MAX) {
			continue;
		}

		if(Primitive(parent) != undecided) {
			continue;
		} else {
			childMoves = GenerateMoves(parent);
		}

		while(1) {
			theMove = childMoves->move;
			child = DoMove(parent, theMove);

			if(kLoopy && gUseOpen) {
				pdata = GetOpenData(parent);
				cdata = GetOpenData(child);
				level = GetLevelNumber(pdata);
			}

			/* If the level is more than the number in tree, resize to handle more levels */

			if(level > (GameTree.NumberOfLevels - 1)) {
				resizeCount++;
				ResizeTree(&GameTree, level);
			}

			(((GameTree.edges)[level])[(GameTree.nextEdgeInLevel)[level]]).Parent = parent;
			(((GameTree.edges)[level])[(GameTree.nextEdgeInLevel)[level]]).Child = child;
			(GameTree.nextEdgeInLevel)[level] += 1;

			/* Resize an individual level if no room left */

			if(((GameTree.edgesPerLevel)[level] - 2) <= (GameTree.nextEdgeInLevel)[level]) {
				resizeLevelCount++;
				(GameTree.edges)[level] = SafeRealloc((GameTree.edges)[level], (GameTree.edgesPerLevel)[level] * 2 * sizeof(EDGE));
				(GameTree.edgesPerLevel)[level] = (GameTree.edgesPerLevel)[level] * 2;
			}

			if((childMoves = childMoves->next) == NULL) {
				break;
			}
		}
	}
	//printf("Levels resized: %d, tree resized: %d\n", resizeLevelCount, resizeCount);
}
Esempio n. 5
0
	T1(Primitive) Vector4T<Primitive> PlaneFit(
        const Vector3T<Primitive>& pt0,
		const Vector3T<Primitive>& pt1,
		const Vector3T<Primitive>& pt2)
	{
			/*
				Note -- this the most straightforward fashion to calculate a plane, but unfortunately it's inaccurate
						(particularly if the points are close together). There are better methods, but they require
						more complex math (see, for example, the Triangle library)
			*/
		auto normal = Normalize( Cross( pt0 - pt1, pt2 - pt1 ) );
		Primitive w = (-Dot( pt0, normal ) - Dot( pt1, normal ) - Dot( pt2, normal )) * Primitive(1./3.);
		return Expand( normal, w );
	}
Esempio n. 6
0
 Primitive operator()(size_t i) const
 {
     const double width =
         grid_[i+1] - grid_[i];
     const double density = masses_[i]/width;
     const double velocity = momenta_[i]/masses_[i];
     const double thermal_energy =
         energies_[i]/masses_[i] -
         0.5*pow(velocity,2);
     const double pressure =
         eos_.de2p(density, thermal_energy);
     return Primitive(density,
                      pressure,
                      velocity);
 }
Esempio n. 7
0
MOVELIST *GenerateMoves(POSITION position)
{
	// Here, use head = CreateMovelistNode(move,head) ;
	// then return head when done
	MOVELIST *CreateMovelistNode(), *head = NULL;
	int i, j;

	if(Primitive(position) == undecided)
	{
		position /= 2;
		for(i = 0; i < rows; i++)
		{
			int piecesinrow = position % 8;
			position = position >> 3;
			for(j = 1; j <= piecesinrow; j++)
				head = CreateMovelistNode( (MOVE)((i+1)*10 + j), head);
		}
	}
Esempio n. 8
0
    T1(Primitive) bool PlaneFit_Checked(
        Vector4T<Primitive>* result,
        const Vector3T<Primitive>& pt0,
		const Vector3T<Primitive>& pt1,
		const Vector3T<Primitive>& pt2)
	{
        assert(result);
			/*
				Note -- this the most straightforward fashion to calculate a plane, but unfortunately it's inaccurate
						(particularly if the points are close together). There are better methods, but they require
						more complex math (see, for example, the Triangle library)
			*/
		Vector3T<Primitive> normal;
        if (!Normalize_Checked(&normal, Cross(pt0 - pt1, pt2 - pt1)))
            return false;

        auto w = (-Dot( pt0, normal ) - Dot( pt1, normal ) - Dot( pt2, normal )) * Primitive(1./3.);
		*result = Expand( normal, w );
        return true;
	}
Esempio n. 9
0
double Prmv(char chaine[], char variable, double valeur, void *donnees)
{
    if (!donnees)
       return ERR_PARAM;
    OptionsAlgo *optn = (OptionsAlgo*) donnees;

    double param[5] = {0};
    char *tab[5] = {NULL};
    tab[0] = malloc(MAX_CHAINE);
    tab[0][0] = '\0';
    tab[1] = malloc(MAX_CHAINE);
    tab[1][0] = '\0';

    RecupererParametres(chaine, param, 5, variable, valeur, tab, MAX_CHAINE);
    if (param[2] >= CODE_ERREUR || param[3] >= CODE_ERREUR || param[4] >= CODE_ERREUR || !tab[0][0] || !tab[1][0] || tab[1][1])
    {
       free(tab[0]); free(tab[1]);
       return ERR_PARAM;
    }

    double a = Primitive(tab[0], tab[1][0], param[2], param[3], param[4], *optn);
    free(tab[0]); free(tab[1]);
    return a;
}
Esempio n. 10
0
Primitive Primitive::operator*(double s)
{
	return Primitive(this->density*s,this->pressure*s,this->velocity*s,this->entropy*s);
}
Esempio n. 11
0
VALUE DetermineZeroValue(POSITION position)
{
	POSITION i,lowSeen,highSeen;
	POSITION numUndecided, oldNumUndecided, numNew;
	MOVELIST *moveptr, *headMove;
	POSITION child;
	VALUE childValue;
	POSITION numTot, numWin, numTie;
	int tieRemoteness, winRemoteness;

	//if (gTwoBits)
	//    InitializeVisitedArray();

	StoreValueOfPosition(position,Primitive(position));
	MarkAsVisited(position);
	oldNumUndecided = 0;
	numUndecided = 1;
	numNew = 1;

	lowSeen = position;
	highSeen = lowSeen+1;

	while((numUndecided != oldNumUndecided) || (numNew != 0)) {

		oldNumUndecided = numUndecided;
		numUndecided = 0;
		numNew = 0;
		for(i = lowSeen; i <= highSeen; i++) {
			if(Visited(i)) {
				if(GetValueOfPosition(i) == undecided) {
					moveptr = headMove = GenerateMoves(i);
					numTot = numWin = numTie = 0;
					tieRemoteness = winRemoteness = REMOTENESS_MAX;
					while(moveptr != NULL) {
						child = DoMove(i,moveptr->move);
						numTot++;
						if(Visited(child))
							childValue = GetValueOfPosition(child);
						else{
							childValue = Primitive(child);
							numNew++;
							MarkAsVisited(child);
							StoreValueOfPosition(child,childValue);
							if(childValue != undecided) {
								SetRemoteness(child,0);
							}
							if(child < lowSeen) lowSeen = child;
							if(child > highSeen) highSeen = child + 1;
						}

						if(childValue == lose) {
							StoreValueOfPosition(i,win);
							if(Remoteness(i) > Remoteness(child)+1)
								SetRemoteness(i,Remoteness(child)+1);
						}

						if(childValue == win) {
							numWin++;
							if(Remoteness(child) < winRemoteness) {
								winRemoteness = Remoteness(child);
							}
						}
						if(childValue == tie) {
							numTie++;
							if(Remoteness(child) < tieRemoteness) {
								tieRemoteness = Remoteness(child);
							}
						}

						moveptr = moveptr->next;
					}
					FreeMoveList(headMove);
					if((numTot != 0) && (numTot == numWin + numTie)) {
						if(numTie == 0) {
							SetRemoteness(i, winRemoteness+1);
							StoreValueOfPosition(i,lose);
						}else{
							SetRemoteness(i, tieRemoteness+1);
							StoreValueOfPosition(i,tie);
						}
					}

					if(GetValueOfPosition(i) == undecided)
						numUndecided++;
				}
			}
		}

		printf("\nnumUndecided: " POSITION_FORMAT ", diff: " POSITION_FORMAT ", numNew: " POSITION_FORMAT
		       ", lowSeen: " POSITION_FORMAT ", highSeen: " POSITION_FORMAT,
		       numUndecided,numUndecided - oldNumUndecided,numNew,lowSeen,highSeen);

	}

	for(i = 0; i < gNumberOfPositions; i++) {
		if(Visited(i) && (GetValueOfPosition(i) == undecided)) {
			SetRemoteness(i,REMOTENESS_MAX);
			StoreValueOfPosition(i, tie);
		}
		UnMarkAsVisited(i);
	}

	return GetValueOfPosition(position);
}
Esempio n. 12
0
MOVELIST *GenerateMoves(POSITION position) {
	int i, j, t, sumTop, sumBottom;
	int startBin = mancalaL + 1;
	int endBin = mancalaR;
	int *arrayHashedBoard;
	MOVELIST *CreateMovelistNode(), *head = NULL;

	arrayHashedBoard = array_hash(position);
	t = arrayHashedBoard[turn];

	if(t == 0) {
		startBin = mancalaR + 1;
		endBin = boardSize;
	}

	/* sum up the top and bottom rows of bins */
	for(i = mancalaL + 1, j = mancalaR + 1, sumTop = 0, sumBottom = 0;
	    i < mancalaR && j < boardSize;
	    sumTop += arrayHashedBoard[i], sumBottom += arrayHashedBoard[j], i += 1, j += 1) ;

	if(Primitive(position) == undecided) {

		/* on my turn starting, i'm empty -> i get to move from my opponent's bins
		   OR the option is set in which you can choose from any bin on the board */
		if(OPT_WINEMPTY == 2 || OPT_MOVEOPP == 1) {
			if(t == 0 && ((sumBottom == 0 && OPT_WINEMPTY == 2) || OPT_MOVEOPP == 1)) {
				for(i = mancalaL + 1; i < mancalaR; i += 1) {
					if(arrayHashedBoard[i] > 0) {
						head = CreateMovelistNode(i, head);
					}
				}
			}
			else if(t == 1 && ((sumTop == 0 && OPT_WINEMPTY == 2) || OPT_MOVEOPP == 1)) {
				for(i = mancalaR + 1; i < boardSize; i += 1) {
					if(arrayHashedBoard[i] > 0) {
						head = CreateMovelistNode(i, head);
					}
				}
			}
		}

		/* on my turn starting, i'm empty -> i pass */
		if(OPT_WINEMPTY == 4 && ((t == 0 && sumBottom == 0) || (t == 1 && sumTop == 0))  ) {
			head = CreateMovelistNode(0, head);
		}

		/* the default moves available */
		else {
			for(i = startBin; i < endBin; i += 1) {
				if(arrayHashedBoard[i] > 0) {
					head = CreateMovelistNode(i, head);
				}
			}
		}
		SafeFree(arrayHashedBoard);
		if (head == NULL) {
			head = CreateMovelistNode(0, head);
		}
		return head;
	}

	else {
		SafeFree(arrayHashedBoard);
		return NULL;
	}
}
Esempio n. 13
0
void Model_Sonic::createPrimitives(ParserContext &ctx, Geometry &geometry, Polygon &polygon) {
	/* Go through all polygon commands in this polygon and evaluate them, creating
	 * an intermediate Primitive for each vertex segment between BeginVertices
	 * and EndVertices commands. */

	// We already counted the number of primitives while reading the command list
	geometry.primitives.reserve(polygon.primitiveCount);

	// Running vertex buffer

	PrimitiveVertex vertex;

	bool hasVertex = false;
	Primitive *primitive = 0;

	StackMixMap::const_iterator stackMix = ctx.stackMix.end();

	// Default values

	StackBoneMap::const_iterator stackBone = ctx.stackBones.find(polygon.defaultStack);
	ModelNode_Sonic *defaultNode = (stackBone != ctx.stackBones.end()) ? stackBone->second->modelNode : 0;

	if (defaultNode)
		vertex.nodes.push_back(PrimitiveNode(defaultNode, 1.0f));

	Common::Vector3 primScale(ctx.defaultScale, ctx.defaultScale, ctx.defaultScale);

	// Texture dimensions, to convert the texture coordinates to OpenGL notation

	const double tWidth  = !geometry.texture.empty() ? geometry.texture.getTexture().getWidth()  : 1.0f;
	const double tHeight = !geometry.texture.empty() ? geometry.texture.getTexture().getHeight() : 1.0f;


	for (PolygonCommands::const_iterator c = polygon.commands.begin(); c != polygon.commands.end(); ++c) {
		switch(c->command) {
			case kPolygonNOP:
				break;

			case kPolygonBeginVertices:
				geometry.primitives.push_back(Primitive((PrimitiveType) c->parameters[0]));
				primitive = &geometry.primitives.back();

				// We calculated the maximum length of a primitive earlier
				primitive->vertices.reserve(polygon.primitiveSize);
				break;

			case kPolygonEndVertices:
				// We don't strictly need to observe the EndVertices command.
				// In fact, according to some people, the Nintendo DS itself doesn't either.
				break;


			case kPolygonColor:
				// BGR555
				vertex.color[0] = ( c->parameters[0]        & 0x1F) / 31.0f;
				vertex.color[1] = ((c->parameters[0] >>  5) & 0x1F) / 31.0f;
				vertex.color[2] = ((c->parameters[0] >> 10) & 0x1F) / 31.0f;
				break;

			case kPolygonTexCoord:
				// One unit ^= one texel!
				vertex.texCoord[0] = readNintendoFixedPoint( c->parameters[0]        & 0xFFFF, true, 11, 4) / tWidth;
				vertex.texCoord[1] = readNintendoFixedPoint((c->parameters[0] >> 16) & 0xFFFF, true, 11, 4) / tHeight;
				break;

			case kPolygonNormal:
				vertex.normal[0] = readNintendoFixedPoint( c->parameters[0]        & 0x03FF, true, 0, 9);
				vertex.normal[1] = readNintendoFixedPoint((c->parameters[0] >> 10) & 0x03FF, true, 0, 9);
				vertex.normal[2] = readNintendoFixedPoint((c->parameters[0] >> 20) & 0x03FF, true, 0, 9);
				break;


			case kPolygonVertex16:
				vertex.vertex[0] = readNintendoFixedPoint( c->parameters[0]        & 0xFFFF, true, 3, 12);
				vertex.vertex[1] = readNintendoFixedPoint((c->parameters[0] >> 16) & 0xFFFF, true, 3, 12);
				vertex.vertex[2] = readNintendoFixedPoint( c->parameters[1]        & 0xFFFF, true, 3, 12);

				hasVertex = true;
				break;

			case kPolygonVertex10:
				vertex.vertex[0] = readNintendoFixedPoint( c->parameters[0]        & 0x03FF, true, 3, 6);
				vertex.vertex[1] = readNintendoFixedPoint((c->parameters[0] >> 10) & 0x03FF, true, 3, 6);
				vertex.vertex[2] = readNintendoFixedPoint((c->parameters[0] >> 20) & 0x03FF, true, 3, 6);

				hasVertex = true;
				break;

			case kPolygonVertexXY:
				vertex.vertex[0] = readNintendoFixedPoint( c->parameters[0]        & 0xFFFF, true, 3, 12);
				vertex.vertex[1] = readNintendoFixedPoint((c->parameters[0] >> 16) & 0xFFFF, true, 3, 12);

				hasVertex = true;
				break;

			case kPolygonVertexXZ:
				vertex.vertex[0] = readNintendoFixedPoint( c->parameters[0]        & 0xFFFF, true, 3, 12);
				vertex.vertex[2] = readNintendoFixedPoint((c->parameters[0] >> 16) & 0xFFFF, true, 3, 12);

				hasVertex = true;
				break;

			case kPolygonVertexYZ:
				vertex.vertex[1] = readNintendoFixedPoint( c->parameters[0]        & 0xFFFF, true, 3, 12);
				vertex.vertex[2] = readNintendoFixedPoint((c->parameters[0] >> 16) & 0xFFFF, true, 3, 12);

				hasVertex = true;
				break;

			case kPolygonVertexDiff:
				vertex.vertex[0] += readNintendoFixedPoint( c->parameters[0]        & 0x03FF, true, 0, 9) / 8;
				vertex.vertex[1] += readNintendoFixedPoint((c->parameters[0] >> 10) & 0x03FF, true, 0, 9) / 8;
				vertex.vertex[2] += readNintendoFixedPoint((c->parameters[0] >> 20) & 0x03FF, true, 0, 9) / 8;

				hasVertex = true;
				break;


			case kPolygonMatrixRestore:
				if ((stackMix = ctx.stackMix.find(c->parameters[0])) != ctx.stackMix.end()) {
					// Was this stack position filled with kBoneLoadStack?

					vertex.nodes.clear();
					vertex.nodes.reserve(stackMix->second.size());
					for (StackMixes::const_iterator m = stackMix->second.begin(); m != stackMix->second.end(); ++m)
						vertex.nodes.push_back(PrimitiveNode(*m));
				} else if ((stackBone = ctx.stackBones.find(c->parameters[0])) != ctx.stackBones.end()) {
					// Is this a regular bone position?

					vertex.nodes.clear();
					vertex.nodes.push_back(PrimitiveNode(stackBone->second->modelNode, 1.0f));
				}

				// Reset the scale
				primScale[0] = 1.0f;
				primScale[1] = 1.0f;
				primScale[2] = 1.0f;
				break;

			case kPolygonMatrixScale:
				// The NDS probably directly scales the current matrix?
				primScale[0] *= readNintendoFixedPoint(c->parameters[0], true, 19, 12);
				primScale[1] *= readNintendoFixedPoint(c->parameters[1], true, 19, 12);
				primScale[2] *= readNintendoFixedPoint(c->parameters[2], true, 19, 12);
				break;

			// Commands we hopefully won't need
			case kPolygonMatrixMode:
			case kPolygonMatrixPush:
			case kPolygonMatrixPop:
			case kPolygonMatrixStore:
			case kPolygonMatrixIdentity:
			case kPolygonMatrixLoad4x4:
			case kPolygonMatrixLoad4x3:
			case kPolygonMatrixMult4x4:
			case kPolygonMatrixMult4x3:
			case kPolygonMatrixMult3x3:
			case kPolygonMatrixTranslate:
			case kPolygonPolygonAttrib:
			case kPolygonTexImageParam:
			case kPolygonPaletteBase:
			case kPolygonDiffuseAmbient:
			case kPolygonSpecularEmit:
			case kPolygonLightVector:
			case kPolygonLightColor:
			case kPolygonShininess:
			case kPolygonSwapBuffers:
			case kPolygonViewport:
			case kPolygonBoxTest:
			case kPolygonPosTest:
			case kPolygonVecTest:
				throw Common::Exception("Unsupported polygon command: 0x%02X", (uint) c->command);

			default:
				throw Common::Exception("Invalid polygon command: 0x%02X", (uint) c->command);
		}

		if (hasVertex && primitive) {
			/* TODO: We're disabling primitives with mixed stack positions here.
			 *       To support this, we need a way to properly average several
			 *       matrices in evaluatePrimitive(). */
			if (vertex.nodes.size() > 1)
				primitive->invalid = true;

			primitive->vertices.push_back(vertex);
			primitive->vertices.back().vertex.multiply(primScale);

			hasVertex = false;
		}
	}

}
unsigned int TriangleAdjacencyGraph::calcOptPrim ( unsigned extIteration,
    bool doStrip, bool doFan, 
    unsigned minFanTriangles )
{
  int iteration = extIteration;
  bool sample = iteration > 1 ? true : false;
  bool checkRevOrder = sample;
  TriangleList degreeBag[4];
  TriangleList *fList = 0;
  int cost = 0, sampleCost = 0;
  int stripCost = 0, revCost = 0, fanCost = 0, triCost = 0;
  int bestCost = 0, worstCost = 0, lowDegree;
  unsigned int i, n;
  WalkCase walkCase = START;
  Triangle *triangle, *next;
  HalfEdge *twin = 0, *gateEdge = 0, *halfEdge = 0;
  bool doMainLoop = true;
  unsigned int seed = 1, bestSeed = 1;
  int mostDegree = 3;
  unsigned triangleLeft = _trianglePool.countElem();
  srand(1);

  if (doFan) {
    n = _temporaryVector.size();
    fanCost = 0;

    // find fans 

    for (i = 0; i < n; i++) 
      if ( (_temporaryVector[i].size() >= minFanTriangles) &&
	  (gateEdge = _temporaryVector[i][0].second) &&
	  (gateEdge->triangle->valid()) ) {
	for ( halfEdge = gateEdge->next->next->twin;
	    (halfEdge && halfEdge->triangle->valid() && (halfEdge != gateEdge));
	    halfEdge = halfEdge->next->next->twin )
	  ;
	if (halfEdge == gateEdge) {
	  // fan is closed; mark every triangle          

	  triangle = 0;
	  fList = new TriangleList;
	  for ( halfEdge = gateEdge;
	      !triangle || (halfEdge != gateEdge);
	      halfEdge = halfEdge->next->next->twin ) {
	    triangle = halfEdge->triangle;
	    _validTriangleBag.release(*triangle);
	    triangle->drop();
	    triangle->state = FAN_PART;
	    fList->add(*triangle);
	  }
	  _fanBag.push_back(Primitive(i,fList));
	  fanCost += (_temporaryVector[i].size() + 2);
	  triangleLeft -= _temporaryVector[i].size();
	}
      }
  }

  if (doStrip && iteration) {

    // push every triangle into the according degree bag

    degreeBag[mostDegree].paste(_validTriangleBag);
    for (triangle = degreeBag[mostDegree].first; triangle; triangle = next) {
      next = triangle->next;
      if (triangle->valid()) {
	if (triangle->state != mostDegree) {
	  degreeBag[mostDegree].release(*triangle);
	  _validTriangleBag.release(*triangle);
	  degreeBag[triangle->state].add( *triangle);
	}
      }
      else {
	cerr << "INVALID TRIANGLE IN VALID TRIANGLE BAG\n" << endl;
      }
    }

    for (iteration--; iteration >= 0; iteration--) {

      seed = iteration ? rand() : bestSeed;
      srand (seed);

      fList = 0;
      cost = 0;
      doMainLoop = true;
      walkCase = START;

      // run the main loop

      while (doMainLoop) {

	switch (walkCase) {
	  case START:      

	    stripCost = 0;
	    triangle = 0;

	    for (lowDegree = 1; lowDegree < 4; lowDegree++)
	      if ((degreeBag[lowDegree].empty() == false)) {
		if (sample) {
		  // pick a random triangle

		  n = degreeBag[lowDegree].countElem() - 1;
		  i = int(float(n) * rand()/float(RAND_MAX));
		  triangle = degreeBag[lowDegree].first;
                  while (i--) 
                     triangle = triangle->next;
		}
		else {
		  // pick the first triangle

		  triangle = degreeBag[lowDegree].first;
		}              
		break;
	      }

	    if (triangle) {

	      // create the new list

	      fList = new TriangleList;

	      // find the best neighbour

	      gateEdge = 0;
	      for (i = 0; i < 3; i++) 
		if ( (twin = triangle->halfEdgeVec[i].twin) && 
		    (twin->triangle->state > 0) ) {
		  if ( twin->next->next->twin &&
		      (twin->next->next->twin->triangle->state > 0) ) {
		    gateEdge = &triangle->halfEdgeVec[i];
		    break;
		  }
		  else {
		    if ( twin->next->twin &&
			(twin->next->twin->triangle->state > 0) )
		      gateEdge = &triangle->halfEdgeVec[i];
		    else {
		      if ((twin->triangle->state > 0))
			gateEdge = &triangle->halfEdgeVec[i];
		    }
		  }
		}

	      // release and store the first triangle

	      dropOutTriangle (*triangle,degreeBag);
	      fList->add(*triangle);
	      stripCost += 3;

	      // set the next step

	      if (gateEdge) {          
		walkCase = LEFT;
		stripCost++;
	      }
	      else 
		walkCase = FINISH;
	    }
	    else
	      doMainLoop = false;      
	    break;

	  case LEFT:
	    gateEdge = gateEdge->twin;
	    triangle = gateEdge->triangle;

	    // find the next gate

	    if (triangle->state == DEGREE_0) {
	      gateEdge = 0;
	      walkCase = FINISH;
	    }
	    else
	      if ( (twin = gateEdge->next->next->twin) && 
		  (twin->triangle->state > 0) ){
		gateEdge = gateEdge->next->next;
		stripCost++;
		walkCase = RIGHT;
	      }
	      else {
		gateEdge = gateEdge->next;
		stripCost += 2;
		walkCase = LEFT;
	      }

	    // store the current triangle

	    dropOutTriangle (*triangle,degreeBag);
	    fList->add(*triangle);
	    break;

	  case RIGHT:      
	    gateEdge = gateEdge->twin;
	    triangle = gateEdge->triangle;

	    // find the next gate

	    if (triangle->state == DEGREE_0) {
	      gateEdge = 0;
	      walkCase = FINISH;
	    }
	    else
	      if ( (twin = gateEdge->next->twin) && 
		  (twin->triangle->state > 0) ) {
		gateEdge = gateEdge->next;
		stripCost++;
		walkCase = LEFT;
	      }
	      else {
		gateEdge = gateEdge->next->next;
		stripCost += 2;
		walkCase = RIGHT;
	      }

	    // store the current triangle

	    dropOutTriangle (*triangle,degreeBag);
	    fList->add(*triangle);
	    break;

	  case FINISH:      
	    // try to reverse the strip

	    if ( checkRevOrder &&
		(revCost = calcStripCost(*fList,true)) &&
		(revCost < stripCost) ) {
	      _stripBag.push_back(Primitive(1,fList));
	      cost += revCost;
	    }
	    else {
	      _stripBag.push_back(Primitive(0,fList));
	      cost += stripCost;
	    }
	    walkCase = START;
	    fList = 0;
	    break;
	}  
      }

      if (sample) {
	sampleCost = cost + (degreeBag[0].countElem() * 3) + fanCost;
	if (!bestCost || (sampleCost < bestCost)) {
	  bestCost = sampleCost;
	  bestSeed = seed;
	}
	if (sampleCost > worstCost)
	  worstCost = sampleCost;

	cout << " cost/best/worst: " 
	  << sampleCost << '/' << bestCost << '/' << worstCost
	  << endl;
      }

      if (iteration) {
	// reinit the four degree bags

	degreeBag[mostDegree].paste(degreeBag[0]);
	n = _stripBag.size();
	for (i = 0; i < n; i++) {
	  degreeBag[mostDegree].paste(*_stripBag[i].second);
	  delete _stripBag[i].second;
	}
	_stripBag.clear();
	for ( triangle = degreeBag[mostDegree].first; triangle; 
	    triangle = next) {
	  next = triangle->next;
	  triangle->resetDegreeState(STRIP_PART);
	  if (triangle->valid()) {
	    if (triangle->state != mostDegree) {
	      degreeBag[mostDegree].release(*triangle);
	      degreeBag[triangle->state].add(*triangle);
	    }
	  }
	  else {
	    cerr << "INVALID TRIANGLE IN REINIT\n" << endl;
	    cerr << triangle->state << endl;
	  }
	}
      }
    }
  }
  else {    
    // push every valid triangle in degree 0; we don't strip anything

    degreeBag[0].paste(_validTriangleBag);
  }

  if (sample) {
    cerr << "range: " 
      << bestCost << '/' << worstCost << ' '
      << float(100 * (worstCost-bestCost))/float(bestCost) << '%'
      << endl;
  }

  // collect isolated triangles  

  degreeBag[0].paste(_invalidTriangleBag);  
  triCost = degreeBag[0].countElem() * 3;
  if (triCost) {
    fList = new TriangleList;  
    fList->paste(degreeBag[0]);
    _triBag.push_back(Primitive(0,fList));
  }

  return (cost + fanCost + triCost);
}                                                  
Esempio n. 15
0
Primitive Primitive::operator/(double s)
{
	return Primitive(this->density/s, this->pressure/s, this->velocity/s,this->entropy/s);
}
Esempio n. 16
0
Primitive eval(Ast *astNode) {
	// Switch cases == glorified GOTO == lame
	// I waste stack space like its my job
	Primitive v, left, right;
	std::string funcName;
	std::map<std::string, Ast*>::const_iterator itr;
	std::map<std::string, Primitive> newstackframe;
	std::map<std::string, Primitive>::const_iterator stackitr;
	
	// Function call and param stuff
	std::list<Parameter> functionparams;
	std::list<Parameter> callparams;
	std::list<Parameter>::const_iterator paramitr;
	std::vector<Primitive> *vec;
	std::vector<Primitive> vec2;	
	std::vector<Parameter> members;
	switch( astNode->getNodetype() ) {
		case 'F': 
			// Function only has a left branch
			v = eval(astNode->getLeft()); 
			break;
		case 'S': 
			// Only need to eval the right hand side since thats your return statement
			// The left hand side is either a no op, or the line before that does not matter
			eval(astNode->getLeft()); 
			v = eval(astNode->getRight()); 
			break; 
		case 'A':
			// Handle the right hand side of an array declaration
			// Set the values to real values
			vec = new std::vector<Primitive>();
			members = *astNode->getMembers();
			for(int i=0;i<members.size();i++) {
				if(members[i].name == "") {
					vec->push_back(members[i].value);
				} else {
					stackitr = executionstack.top().find(members[i].name);
					if(stackitr == executionstack.top().end()) {
						std::cout << "	Semantics error: undefined variables in array declaration" << std::endl;				
						exit (EXIT_FAILURE);
					}
					vec->push_back(executionstack.top()[members[i].name]);
				}
			}
			v = Primitive(vec);
			v.type = ARRAY;
			break;
		case 'a':
			// Handle rhs of a array index value retrieval
			stackitr = executionstack.top().find(astNode->getName());
			if(stackitr == executionstack.top().end()) {
				std::cout << "	Semantics error: list named " << astNode->getName() << " not defined" << std::endl;				
				exit (EXIT_FAILURE);
			}
			
			vec2 = *(executionstack.top()[astNode->getName()].array);
			v = vec2[(int)eval(astNode->getLeft()).value];
			break;
		case 'l':
			// Handle len()
			stackitr = executionstack.top().find(astNode->getName());
			if(stackitr == executionstack.top().end()) {
				std::cout << "	Semantics error: list named " << astNode->getName() << " not defined" << std::endl;				
				exit (EXIT_FAILURE);
			}
			if(executionstack.top()[astNode->getName()].type != ARRAY) {
				std::cout << "	Semantics error: " << astNode->getName() << " is not a list, cant call len()" << std::endl;				
				exit (EXIT_FAILURE);
			}
			vec2 = *(executionstack.top()[astNode->getName()].array);
			v = Primitive((int)vec2.size());
			break;
		case 'm':
			// Handle list.append(expr) and list.pop(expr)
			stackitr = executionstack.top().find(astNode->getName());
			if(stackitr == executionstack.top().end()) {
				std::cout << "	Semantics error: list named " << astNode->getName() << " not defined" << std::endl;				
				exit (EXIT_FAILURE);
			}
			if(executionstack.top()[astNode->getName()].type != ARRAY) {
				std::cout << "	Semantics error: " << astNode->getName() << " is not a list, cant call append()" << std::endl;				
				exit (EXIT_FAILURE);
			}
			if(astNode->getMethod() == "append") {
				executionstack.top()[astNode->getName()].array->push_back(eval(astNode->getLeft()));
			} else if(astNode->getMethod() == "pop") {
				executionstack.top()[astNode->getName()].array->pop_back();
			} else {
				std::cout << "	Semantics error: " << astNode->getMethod()  << " method not supported" << std::endl;				
				exit (EXIT_FAILURE);
			}
			
			break;	
		case 'C':
			// Get function node and evaluate it
			funcName = astNode->getName();
		 	itr = functions.find(funcName);
			if(itr == functions.end()) {
				std::cout << "	Semantics error: no function \"" << funcName << "\" found!" << std::endl;				
				exit (EXIT_FAILURE);
			}
			
			// If they try to call main, stop them
			if(funcName == "main") {
				std::cout << "	Semantics error: Not allowed to call \"main()\", duh." << std::endl;
				exit (EXIT_FAILURE);
			}
			
			// Match given parameters to function signature in number only (no typing for piethon)
			functionparams = *itr->second->getParams();
			callparams = *astNode->getParams();
			if(functionparams.size() != callparams.size()) {
				std::cout << "	Semantics error: given parameters do not match function signature of \"" << funcName << "\"!" << std::endl;				
				exit (EXIT_FAILURE);
			}
			
			// New stack with given params included to match signature
			for (paramitr = functionparams.begin(); paramitr != functionparams.end(); ++paramitr) {
				// If identifier get the value of it
				if(callparams.front().name != "") {
					stackitr = executionstack.top().find(callparams.front().name);
					if(stackitr == executionstack.top().end()) {
						std::cout << "	Semantics error: no variable named \"" << callparams.front().name << "\" found!" << std::endl;				
						exit (EXIT_FAILURE);
					}
					newstackframe[(*paramitr).name] = executionstack.top()[callparams.front().name];
				} else {
					// Otherwise just set to value
					newstackframe[(*paramitr).name] = callparams.front().value;
				}
				callparams.pop_front();
			}
			// Push new stack frame
			executionstack.push(newstackframe);
			// Call function
			v = eval(itr->second);
			
			// Pop, back to old stack frame
			executionstack.pop();
			break;
		case '?': 
			// If 
			if((int)eval(astNode->getLeft()).value == 1) {
				v = eval(astNode->getRight()); 	
			}
			break;
		case ':': 
			// If-else
			if((int)eval(astNode->getLeft()).value == 1) {
				v = eval(astNode->getMiddle()); 	
			} else {
				v = eval(astNode->getRight()); 	
			}
			break;
		case 'w': 
			// while
			while((int)eval(astNode->getLeft()).value == 1) {
				v = eval(astNode->getRight()); 	
			}
			break;
		case 'I': 
			// Look up value in table
			stackitr = executionstack.top().find(astNode->getName());
			if(stackitr == executionstack.top().end()) {
				std::cout << "	Semantics error: no variable \"" << astNode->getName() << "\" found!" << std::endl;				
				return 0;
			}
			v = executionstack.top()[astNode->getName()];
			break;
		case '=':
			// Set value of identifier in table
			if(astNode->getLeft()->getNodetype() == 'a') {
				vec2 = *(executionstack.top()[astNode->getLeft()->getName()].array);
				vec2[(int)eval(astNode->getLeft()->getLeft()).value] = eval(astNode->getRight());
				executionstack.top()[astNode->getLeft()->getName()].array->assign(vec2.begin(), vec2.end());
			} else {
				executionstack.top()[astNode->getLeft()->getName()] = eval(astNode->getRight());	
			}
			break;
		case '>':
			if(eval(astNode->getLeft()).value >  eval(astNode->getRight()).value) {
				v = Primitive(1.0); 	
				v.type = BOOLEAN;
			} else {
				v = Primitive(0.0); 	
				v.type = BOOLEAN;
			}
			break;
		case '.':
			if(eval(astNode->getLeft()).value >=  eval(astNode->getRight()).value) {
				v = Primitive(1.0); 	
				v.type = BOOLEAN;
			} else {
				v = Primitive(0.0); 	
				v.type = BOOLEAN;
			}
			break;
		case '<':
			if(eval(astNode->getLeft()).value <  eval(astNode->getRight()).value) {
				v = Primitive(1.0); 	
				v.type = BOOLEAN;
			} else {
				v = Primitive(0.0); 	
				v.type = BOOLEAN;
			}
			break;
		case ',':
			if(eval(astNode->getLeft()).value <=  eval(astNode->getRight()).value) {
				v = Primitive(1.0); 	
				v.type = BOOLEAN;
			} else {
				v = Primitive(0.0); 	
				v.type = BOOLEAN;
			}
			break;

		case '~':
			if(eval(astNode->getLeft()).value == eval(astNode->getRight()).value) {
				v = Primitive(1.0); 	
				v.type = BOOLEAN;
			} else {
				v = Primitive(0.0); 	
				v.type = BOOLEAN;
			}
			break;	
		case '!':
			if(eval(astNode->getLeft()).value != eval(astNode->getRight()).value) {
				v = Primitive(1.0); 	
				v.type = BOOLEAN;
			} else {
				v = Primitive(0.0); 	
				v.type = BOOLEAN;
			}
			break;			
		case 'n': 
			// Do nothing!
		break;
		case 'P':
			// Handle printing short string messages
			if(astNode->getName() != "") {
				std::cout << astNode->getName();
			} else {
			
			 	// Print stuff
				v = eval(astNode->getLeft());
				if(v.type == INTEGER) {
					printf("%d\n", (int)v.value); 
				} 
				if(v.type == FLOATING) {
					printf("%lf\n", v.value); 
				}
				// Arrays of arrays not really allowed to print
				if(v.type == ARRAY) {
					std::vector<Primitive> vec = *v.array;
					printf("[");
					for(int i=0;i<vec.size();i++) {
						if(vec[i].type == INTEGER) {
							printf("%d,", (int)vec[i].value); 
						} 
						if(vec[i].type == FLOATING) {
							printf("%lf,", vec[i].value); 
						}
					}
					printf("]\n");
				}
			}
			break;
		case 'R': v = eval(astNode->getLeft()); break; 
		
		case 'K': v = astNode->getNumber(); break;
		case '+': 
			left = eval(astNode->getLeft());
			right = eval(astNode->getRight());
			v = Primitive(left.value + right.value); 	
			v.type = getType(left, right);
			break;
		case '-': 
			left = eval(astNode->getLeft());
			right = eval(astNode->getRight());
			v = Primitive(left.value - right.value); 	
			v.type = getType(left, right);
			break;
		case '*': 
			left = eval(astNode->getLeft());
			right = eval(astNode->getRight());
			v = Primitive(left.value * right.value); 	
			v.type = getType(left, right);
		break;
		case '/': 
			left = eval(astNode->getLeft());
			right = eval(astNode->getRight());
			v = Primitive(left.value / right.value); 	
			v.type = getType(left, right);
			break;		
		break;
		case '%': 
			left = eval(astNode->getLeft());
			right = eval(astNode->getRight());
			v = Primitive(fmod(left.value, right.value)); 	
			v.type = getType(left, right);
			break;		
		case '^': 
			left = eval(astNode->getLeft());
			right = eval(astNode->getRight());
			v = Primitive(pow(left.value, right.value)); 	
			v.type = getType(left, right);
			break;		
		
		case 'M': v = Primitive(-1 * eval(astNode->getLeft()).value ); break;
		default: std::cout << "internal error: bad node "
			<< astNode->getNodetype() << std::endl;
	}
	return v;
}
Esempio n. 17
0
Primitive Primitive::operator+(Primitive const & other)const
{
	return Primitive(this->density + other.density, this->pressure + other.pressure, this->velocity + other.velocity,
		this->entropy+other.entropy);
}