Exemple #1
0
UCS4 *Parser::Convert_UTF8_To_UCS4(const unsigned char *text_array, int text_array_size, int *char_array_size)
{
	UCS4 *char_array = NULL;
	UCS4 chr;
	int i, j, k, seqlen;

	if((text_array == NULL) || (text_array_size == 0) || (char_array_size == NULL))
		return NULL;

	char_array = reinterpret_cast<UCS4 *>(POV_MALLOC(text_array_size * sizeof(UCS4), "Character Array"));
	if(char_array == NULL)
		throw POV_EXCEPTION_CODE(kOutOfMemoryErr);

	for(i = 0, k = 0; i < text_array_size; k++, i++)
	{
		seqlen = gUTF8SequenceArray[text_array[i]];
		chr = 0;
		for(j = seqlen; j > 0; j--)
		{
			chr += text_array[i];
			chr <<= 6;
			i++;
		}
		chr += text_array[i];

		char_array[k] = chr - gUTF8Offsets[seqlen];
	}

	char_array = reinterpret_cast<UCS4 *>(POV_REALLOC(char_array, k * sizeof(UCS4), "Character Array"));
	*char_array_size = k;

	return char_array;
}
Exemple #2
0
FUNCTION POVFPU_AddConstant(DBL v)
{
	unsigned int i;

	if(POVFPU_Consts == NULL)
	{
		POVFPU_Consts = (DBL *)POV_MALLOC(sizeof(DBL), "fn: constant floats");
		POVFPU_Consts[0] = v;
		POVFPU_ConstCnt = 1;
		return 0;
	}

	for(i = 0; i < POVFPU_ConstCnt; i++)
	{
		if(POVFPU_Consts[i] == v)
			return (unsigned int)i;
	}

	if(POVFPU_ConstCnt == MAX_K)
		Error("More than %d constants in all functions are not supported.", (int)MAX_K);

	POVFPU_ConstCnt++;
	POVFPU_Consts = (DBL *)POV_REALLOC(POVFPU_Consts, sizeof(DBL) * POVFPU_ConstCnt, "fn: constant floats");
	POVFPU_Consts[POVFPU_ConstCnt - 1] = v;

	return POVFPU_ConstCnt - 1;
}
Exemple #3
0
// Create a bounding box hierarchy from a given list of finite and
// infinite elements. Each element consists of
//
// - an infinite flag
// - a bounding box enclosing the element
// - a pointer to the structure representing the element (e.g an object)
void Build_BBox_Tree(BBOX_TREE **Root, size_t numOfFiniteObjects, BBOX_TREE **&Finite, size_t numOfInfiniteObjects, BBOX_TREE **Infinite, size_t& maxfinitecount)
{
    ptrdiff_t low, high;
    BBOX_TREE *cd, *root;

    // This is a resonable guess at the number of finites needed.
    // This array will be reallocated as needed if it isn't.
    maxfinitecount = 2 * numOfFiniteObjects;

    // Now do a sort on the objects, with the end result being
    // a tree of objects sorted along the x, y, and z axes.
    if(numOfFiniteObjects > 0)
    {
        low = 0;
        high = numOfFiniteObjects;

        while(sort_and_split(Root, Finite, &numOfFiniteObjects, low, high, maxfinitecount) == 0)
        {
            low = high;
            high = numOfFiniteObjects;
        }

        // Move infinite objects in the first leaf of Root.
        if(numOfInfiniteObjects > 0)
        {
            root = *Root;
            root->Node = reinterpret_cast<BBOX_TREE **>(POV_REALLOC(root->Node, (root->Entries + 1) * sizeof(BBOX_TREE *), "composite"));
            POV_MEMMOVE(&(root->Node[1]), &(root->Node[0]), root->Entries * sizeof(BBOX_TREE *));
            root->Entries++;
            cd = create_bbox_node(numOfInfiniteObjects);
            for(size_t i = 0; i < numOfInfiniteObjects; i++)
                cd->Node[i] = Infinite[i];

            calc_bbox(&(cd->BBox), Infinite, 0, numOfInfiniteObjects);
            root->Node[0] = cd;
            calc_bbox(&(root->BBox), root->Node, 0, root->Entries);

            // Root and first node are infinite.
            root->Infinite = true;
            root->Node[0]->Infinite = true;
        }
    }
    else
    {
        // There are no finite objects and no Root was created.
        // Create it now and put all infinite objects into it.

        if(numOfInfiniteObjects > 0)
        {
            cd = create_bbox_node(numOfInfiniteObjects);
            for(size_t i = 0; i < numOfInfiniteObjects; i++)
                cd->Node[i] = Infinite[i];
            calc_bbox(&(cd->BBox), Infinite, 0, numOfInfiniteObjects);
            *Root = cd;
            (*Root)->Infinite = true;
        }
    }
}
Exemple #4
0
UCS2 *Parser::UCS2_strcat(UCS2 *s1, const UCS2 *s2)
{
	int l1, l2;

	l1 = UCS2_strlen(s1);
	l2 = UCS2_strlen(s2);

	s1 = reinterpret_cast<UCS2 *>(POV_REALLOC(s1, sizeof(UCS2) * (l1 + l2 + 1), "UCS2 String"));

	UCS2_strcpy(&s1[l1], s2);

	return s1;
}
static void priority_queue_insert(PRIORITY_QUEUE *Queue, DBL Depth, BBOX_TREE *Node)
{
  unsigned size;
  int i;
  QELEM tmp;
  QELEM *List;

#ifdef BBOX_EXTRA_STATS
  Increase_Counter(stats[totalQueues]);
#endif

  Queue->QSize++;

  size = Queue->QSize;

  /* Reallocate priority queue if it's too small. */

  if (size >= Queue->Max_QSize)
  {
    if (size >= INT_MAX/2)
    {
      Error("Priority queue overflow.");
    }

#ifdef BBOX_EXTRA_STATS
    Increase_Counter(stats[totalQueueResizes]);
#endif

    Queue->Max_QSize *= 2;

    Queue->Queue = (QELEM *)POV_REALLOC(Queue->Queue, Queue->Max_QSize*sizeof(QELEM), "priority queue");
  }

  List = Queue->Queue;
  
  List[size].Depth = Depth;
  List[size].Node  = Node;
  
  i = size;
  
  while (i > 1 && List[i].Depth < List[i / 2].Depth)
  {
    tmp = List[i];

    List[i] = List[i / 2];

    List[i / 2] = tmp;

    i = i / 2;
  }
}
Exemple #6
0
void POVFPU_SetGlobal(unsigned int k, DBL v)
{
	if(POVFPU_Globals == NULL)
	{
		POVFPU_GlobalCnt = k + 1;
		POVFPU_Globals = (DBL *)POV_MALLOC(sizeof(DBL) * POVFPU_GlobalCnt, "fn: globals");
	}
	else if(POVFPU_GlobalCnt < k + 1)
	{
		POVFPU_GlobalCnt = k + 1;
		POVFPU_Globals = (DBL *)POV_REALLOC(POVFPU_Globals, sizeof(DBL) * POVFPU_GlobalCnt, "fn: globals");
	}

	POVFPU_Globals[k] = v;
}
void Reinitialize_VLBuffer_Code()
{
  if (Node_Queue->QSize >= Node_Queue->Max_QSize)
  {
    if (Node_Queue->QSize >= INT_MAX/2)
    {
      Error("Node queue overflow.");
    }

    Node_Queue->Max_QSize *= 2;

    Node_Queue->Queue = (PROJECT_TREE_NODE **)POV_REALLOC(Node_Queue->Queue,
      Node_Queue->Max_QSize*sizeof(PROJECT_TREE_NODE *),
      "vista/light buffer node queue");
  }
}
Exemple #8
0
void POVFPU_SetLocal(unsigned int k, DBL v)
{
	if(k >= POVFPU_Current_Context->maxdblstacksize)
	{
		#if (SYS_FUNCTIONS == 1)
		unsigned long diff = ((unsigned long)(POVFPU_Current_Context->dblstack)) - ((unsigned long)(POVFPU_Current_Context->dblstackbase));
		#endif

		POVFPU_Current_Context->maxdblstacksize = max(k + 1, (unsigned int)256);
		POVFPU_Current_Context->dblstackbase = (DBL *)POV_REALLOC(POVFPU_Current_Context->dblstackbase, sizeof(DBL) * POVFPU_Current_Context->maxdblstacksize, "fn: stack");

		#if (SYS_FUNCTIONS == 1)
		POVFPU_Current_Context->dblstack = (DBL *)(((unsigned long)(POVFPU_Current_Context->dblstackbase)) + diff);
		#endif
	}

	POVFPU_Current_Context->dblstackbase[k] = v;
}
Exemple #9
0
void POVFPU_RemoveFunction(FUNCTION fn)
{
	if((POVFPU_Functions == NULL) || (fn >= POVFPU_FunctionCnt))
		return;

	if(POVFPU_Functions[fn].reference_count > 0) // necessary to prevent any recursion
	{
		POVFPU_Functions[fn].reference_count--;

		if(POVFPU_Functions[fn].reference_count == 0)
		{
			// The copying is necessary because recursive POVFPU_RemoveFunction
			// calls may shrink the POVFPU_Functions array and remove the data
			// before we are done with it here! [trf]
			FunctionEntry f = POVFPU_Functions[fn];
			unsigned int i = 0;

			SYS_DELETE_FUNCTION(&f);
			for(i = 0; i < f.fn.program_size; i++)
			{
				if(GET_OP(f.fn.program[i]) == OPCODE_CALL)
					POVFPU_RemoveFunction(GET_K(f.fn.program[i]));
			}
			FNCode_Delete(&(f.fn));

			for(i = POVFPU_FunctionCnt - 1; i > 0; i--)
			{
				if(POVFPU_Functions[i].reference_count == 0)
					POVFPU_FunctionCnt--;
				else
					break;
			}

			if(POVFPU_FunctionCnt == 0)
			{
				POV_FREE(POVFPU_Functions);
				POVFPU_Functions = NULL;
			}
			else
				POVFPU_Functions = (FunctionEntry *)POV_REALLOC(POVFPU_Functions, sizeof(FunctionEntry) * POVFPU_FunctionCnt, "fn: FunctionEntry");
		}
	}
}
Exemple #10
0
FUNCTION POVFPU_AddFunction(FunctionCode *f)
{
	FUNCTION fn = 0;

	if(POVFPU_Functions == NULL)
	{
		POVFPU_Functions = (FunctionEntry *)POV_MALLOC(sizeof(FunctionEntry), "fn: FunctionEntry");
		POVFPU_Functions[0].fn = *f;
		POVFPU_Functions[0].reference_count = 1;
		SYS_ADD_FUNCTION(fn);
		POVFPU_FunctionCnt = 1;

		return 0;
	}

	if(POVFPU_FunctionCnt == MAX_FN)
	{
		for(fn = 0; fn < MAX_FN; fn++)
		{
			if(POVFPU_Functions[fn].reference_count == 0)
				break;
		}

		if(fn == MAX_K)
			Error("Maximum number (%d) of functions per scene reached.", MAX_FN);
	}
	else
	{
		fn = POVFPU_FunctionCnt;
		POVFPU_FunctionCnt++;
	}

	POVFPU_Functions = (FunctionEntry *)POV_REALLOC(POVFPU_Functions, sizeof(FunctionEntry) * POVFPU_FunctionCnt, "fn: FunctionEntry");
	POVFPU_Functions[fn].fn = *f;
	POVFPU_Functions[fn].reference_count = 1;
	SYS_ADD_FUNCTION(fn);

	return fn;
}
Exemple #11
0
void Insert_Spline_Entry(SPLINE * sp, DBL p, EXPRESS v)
{
    int i, k;

    /* Reset the Coeffs_Computed flag.  Inserting a new point invalidates 
     *  pre-computed coefficients */
    sp->Coeffs_Computed = false;
    sp->Cache_Valid = false;
    /* If all space is used, reallocate */
    if(sp->Number_Of_Entries >= sp->Max_Entries)
    {
        sp->Max_Entries += INIT_SPLINE_SIZE;
        sp->SplineEntries = (SPLINE_ENTRY *)POV_REALLOC(sp->SplineEntries, sp->Max_Entries * sizeof(SPLINE_ENTRY), "Temporary Spline Entries");
        for (i = sp->Number_Of_Entries; i < sp->Max_Entries; i++)
        {
          sp->SplineEntries[i].par=-1e6;
        }
    }
    i = findt(sp, p);
    /* If p is already in spline, replace */
    /* The clause after the || is needed because findt returns sp->Number_Of_Entries
     * if p is greater than OR EQUAL TO the highest par in the spline */
    if(sp->Number_Of_Entries != 0 && ((sp->SplineEntries[i].par == p) || (i == sp->Number_Of_Entries && sp->SplineEntries[i-1].par == p)))
    {
        for(k=0; k<5; k++)
            sp->SplineEntries[i].vec[k] = v[k];
    }
    else
    {
        mkfree(sp, i);
        sp->SplineEntries[i].par = p;

        for(k=0; k<5; k++)
            sp->SplineEntries[i].vec[k] = v[k];

        sp->Number_Of_Entries += 1;
    }
}
Exemple #12
0
static int sort_and_split(BSPHERE_TREE **Root, BSPHERE_TREE ***Elements, int *nElem, int first, int last, int& maxelements)
{
	int size, i, best_loc;
	DBL *area_left, *area_right;
	DBL best_index, new_index;
	BSPHERE_TREE *cd;

	int Axis = find_axis(*Elements, first, last);

	size = last - first;

	if (size <= 0)
	{
		return (1);
	}

	/*
	 * Actually, we could do this faster in several ways. We could use a
	 * logn algorithm to find the median along the given axis, and then a
	 * linear algorithm to partition along the axis. Oh well.
	 */

	switch(Axis)
	{
		case X:
			QSORT((void *)(*Elements + first), size, sizeof(BSPHERE_TREE *), comp_elements<X>);
			break;
		case Y:
			QSORT((void *)(*Elements + first), size, sizeof(BSPHERE_TREE *), comp_elements<Y>);
			break;
		case Z:
			QSORT((void *)(*Elements + first), size, sizeof(BSPHERE_TREE *), comp_elements<Z>);
			break;
	}

	/*
	 * area_left[] and area_right[] hold the surface areas of the bounding
	 * boxes to the left and right of any given point. E.g. area_left[i] holds
	 * the surface area of the bounding box containing Elements 0 through i and
	 * area_right[i] holds the surface area of the box containing Elements
	 * i through size-1.
	 */

	area_left  = (DBL *)POV_MALLOC(size * sizeof(DBL), "blob bounding hierarchy");
	area_right = (DBL *)POV_MALLOC(size * sizeof(DBL), "blob bounding hierarchy");

	/* Precalculate the areas for speed. */

	build_area_table(*Elements, first, last - 1, area_left);
	build_area_table(*Elements, last - 1, first, area_right);

	best_index = area_right[0] * (size - 3.0);

	best_loc = - 1;

	/*
	 * Find the most effective point to split. The best location will be
	 * the one that minimizes the function N1*A1 + N2*A2 where N1 and N2
	 * are the number of objects in the two groups and A1 and A2 are the
	 * surface areas of the bounding boxes of the two groups.
	 */

	for (i = 0; i < size - 1; i++)
	{
		new_index = (i + 1) * area_left[i] + (size - 1 - i) * area_right[i + 1];

		if (new_index < best_index)
		{
			best_index = new_index;
			best_loc = i + first;
		}
	}

	POV_FREE(area_left);
	POV_FREE(area_right);

	/*
	 * Stop splitting if the BRANCHING_FACTOR is reached or
	 * if splitting stops being effective.
	 */

	if ((size <= BRANCHING_FACTOR) || (best_loc < 0))
	{
		cd = (BSPHERE_TREE *)POV_MALLOC(sizeof(BSPHERE_TREE), "blob bounding hierarchy");

		cd->Entries = (short)size;

		cd->Node = (BSPHERE_TREE **)POV_MALLOC(size*sizeof(BSPHERE_TREE *), "blob bounding hierarchy");

		for (i = 0; i < size; i++)
		{
			cd->Node[i] = (*Elements)[first+i];
		}

		recompute_bound(cd);

		*Root = cd;

		if (*nElem >= maxelements)
		{
			/* Prim array overrun, increase array by 50%. */

			maxelements = 1.5 * maxelements;

			/* For debugging only. */

// TODO FIXME			Debug_Info("Reallocing elements to %d\n", maxelements);

			*Elements = (BSPHERE_TREE **)POV_REALLOC(*Elements, maxelements * sizeof(BSPHERE_TREE *), "bounding slabs");
		}

		(*Elements)[*nElem] = cd;

		(*nElem)++;

		return (1);
	}
	else
	{
		sort_and_split(Root, Elements, nElem, first, best_loc + 1, maxelements);

		sort_and_split(Root, Elements, nElem, best_loc + 1, last, maxelements);

		return (0);
	}
}
Exemple #13
0
UCS2 *Parser::String_To_UCS2(const char *str, bool pathname)
{
	UCS2 *char_string = NULL;
	UCS2 *char_array = NULL;
	int char_array_size = 0;
	int utf8arraysize = 0;
	unsigned char *utf8array = NULL;
	int index_in = 0;
	int index_out = 0;
	char buffer[8];
	char *dummy_ptr = NULL;
	int i = 0;

	if(strlen(str) == 0)
	{
		char_string = reinterpret_cast<UCS2 *>(POV_MALLOC(sizeof(UCS2), "UCS2 String"));
		char_string[0] = 0;

		return char_string;
	}

	switch(sceneData->stringEncoding)
	{
		case 0: // ASCII
			char_array_size = (int)strlen(str);
			char_array = reinterpret_cast<UCS2 *>(POV_MALLOC(char_array_size * sizeof(UCS2), "Character Array"));
			for(i = 0; i < char_array_size; i++)
			{
				if(sceneData->languageVersion < 350)
					char_array[i] = (unsigned char)(str[i]);
				else
				{
					char_array[i] = str[i] & 0x007F;
					if(char_array[i] != str[i])
					{
						char_array[i] = ' ';
						PossibleError("Non-ASCII character has been replaced by space character.");
					}
				}
			}
			break;
		case 1: // UTF8
			char_array = Convert_UTF8_To_UCS2(reinterpret_cast<const unsigned char *>(str), (int)strlen(str), &char_array_size);
			break;
		case 2: // System Specific
			char_array = POV_CONVERT_TEXT_TO_UCS2(reinterpret_cast<const unsigned char *>(str), strlen(str), &char_array_size);
			if(char_array == NULL)
				Error("Cannot convert system specific text format to Unicode.");
			break;
		default:
			Error("Unsupported text encoding format.");
			break;
	}

	if(char_array == NULL)
		Error("Cannot convert text to UCS2 format.");

	char_string = reinterpret_cast<UCS2 *>(POV_MALLOC((char_array_size + 1) * sizeof(UCS2), "UCS2 String"));
	for(index_in = 0, index_out = 0; index_in < char_array_size; index_in++, index_out++)
	{
		if((char_array[index_in] == '\\') && (pathname == false))
		{
			index_in++;

			switch(char_array[index_in])
			{
				case 'a':
					char_string[index_out] = 0x07;
					break;
				case 'b':
					char_string[index_out] = 0x08;
					break;
				case 'f':
					char_string[index_out] = 0x0c;
					break;
				case 'n':
					char_string[index_out] = 0x0a;
					break;
				case 'r':
					char_string[index_out] = 0x0d;
					break;
				case 't':
					char_string[index_out] = 0x09;
					break;
				case 'v':
					char_string[index_out] = 0x0b;
					break;
				case '\0':
					char_string[index_out] = 0x5c;
					break;
				case '\'':
					char_string[index_out] = 0x27;
					break;
				case '\\':
					char_string[index_out] = '\\';
					break;
				case 'u':
					if(index_in + 4 >= char_array_size)
						Error("Unexpected end of escape sequence in text string.");

					buffer[0] = char_array[++index_in];
					buffer[1] = char_array[++index_in];
					buffer[2] = char_array[++index_in];
					buffer[3] = char_array[++index_in];
					buffer[4] = 0;

					char_string[index_out] = (UCS2)strtoul(buffer, &dummy_ptr, 16);
					break;
				default:
					char_string[index_out] = char_array[index_in];
					if ( char_array )
						POV_FREE(char_array);
					char_array = NULL;
					Error( "Illegal escape sequence in string." );
					break;
			}
		}
		else
			char_string[index_out] = char_array[index_in];
	}

	char_string[index_out] = 0;
	index_out++;

	char_string = reinterpret_cast<UCS2 *>(POV_REALLOC(char_string, index_out * sizeof(UCS2), "UCS2 String"));

	if(char_array != NULL)
		POV_FREE(char_array);

	return char_string;
}
static int sort_and_split(BBOX_TREE **Root, BBOX_TREE **&Finite, long *numOfFiniteObjects, long  first, long  last)
{
  BBOX_TREE *cd;
  long size, i, best_loc;
  DBL *area_left, *area_right;
  DBL best_index, new_index;

  Axis = find_axis(Finite, first, last);

  size = last - first;

  if (size <= 0)
  {
    return (1);
  }

  Do_Cooperate(1);

  /*
   * Actually, we could do this faster in several ways. We could use a
   * logn algorithm to find the median along the given axis, and then a
   * linear algorithm to partition along the axis. Oh well.
   */

  QSORT((void *)(&Finite[first]), (unsigned long)size, sizeof(BBOX_TREE *), compboxes);

  /*
   * area_left[] and area_right[] hold the surface areas of the bounding
   * boxes to the left and right of any given point. E.g. area_left[i] holds
   * the surface area of the bounding box containing Finite 0 through i and
   * area_right[i] holds the surface area of the box containing Finite
   * i through size-1.
   */

  area_left = (DBL *)POV_MALLOC(size * sizeof(DBL), "bounding boxes");
  area_right = (DBL *)POV_MALLOC(size * sizeof(DBL), "bounding boxes");

  /* Precalculate the areas for speed. */

  build_area_table(Finite, first, last - 1, area_left);
  build_area_table(Finite, last - 1, first, area_right);

  best_index = area_right[0] * (size - 3.0);

  best_loc = -1;

  /*
   * Find the most effective point to split. The best location will be
   * the one that minimizes the function N1*A1 + N2*A2 where N1 and N2
   * are the number of objects in the two groups and A1 and A2 are the
   * surface areas of the bounding boxes of the two groups.
   */

  for (i = 0; i < size - 1; i++)
  {
    new_index = (i + 1) * area_left[i] + (size - 1 - i) * area_right[i + 1];

    if (new_index < best_index)
    {
      best_index = new_index;
      best_loc = i + first;
    }
  }

  POV_FREE(area_left);
  POV_FREE(area_right);

  /*
   * Stop splitting if the BUNCHING_FACTOR is reached or
   * if splitting stops being effective.
   */

  if ((size <= BUNCHING_FACTOR) || (best_loc < 0))
  {
    cd = create_bbox_node(size);
      
    for (i = 0; i < size; i++)
    {
      cd->Node[i] = Finite[first+i];
    }

    calc_bbox(&(cd->BBox), Finite, first, last);

    *Root = (BBOX_TREE *)cd;

    if (*numOfFiniteObjects > maxfinitecount)
    {
      /* Prim array overrun, increase array by 50%. */

      maxfinitecount = 1.5 * maxfinitecount;

      /* For debugging only. */

      Debug_Info("Reallocing Finite to %d\n", maxfinitecount);

      Finite = (BBOX_TREE **)POV_REALLOC(Finite, maxfinitecount * sizeof(BBOX_TREE *), "bounding boxes");
    }

    Finite[*numOfFiniteObjects] = cd;

    (*numOfFiniteObjects)++;

    return (1);
  }
  else
  {
    sort_and_split(Root, Finite, numOfFiniteObjects, first, best_loc + 1);

    sort_and_split(Root, Finite, numOfFiniteObjects, best_loc + 1, last);

    return (0);
  }
}
void Build_BBox_Tree(BBOX_TREE **Root, long numOfFiniteObjects, BBOX_TREE **&Finite, long  numOfInfiniteObjects, BBOX_TREE  **Infinite)
{
  short i;
  long low, high;
  BBOX_TREE *cd, *root;

  /*
   * This is a resonable guess at the number of finites needed.
   * This array will be reallocated as needed if it isn't.
   */

  maxfinitecount = 2 * numOfFiniteObjects;

  /*
   * Now do a sort on the objects, with the end result being
   * a tree of objects sorted along the x, y, and z axes.
   */

  if (numOfFiniteObjects > 0)
  {
    low = 0;
    high = numOfFiniteObjects;

    while (sort_and_split(Root, Finite, &numOfFiniteObjects, low, high) == 0)
    {
      low = high;
      high = numOfFiniteObjects;

      Do_Cooperate(0);
    }

    /* Move infinite objects in the first leaf of Root. */

    if (numOfInfiniteObjects > 0)
    {
      root = (BBOX_TREE *)(*Root);

      root->Node = (BBOX_TREE **)POV_REALLOC(root->Node, (root->Entries + 1) * sizeof(BBOX_TREE *), "composite");

      POV_MEMMOVE(&(root->Node[1]), &(root->Node[0]), root->Entries * sizeof(BBOX_TREE *));

      root->Entries++;

      cd = create_bbox_node(numOfInfiniteObjects);

      for (i = 0; i < numOfInfiniteObjects; i++)
      {
        cd->Node[i] = Infinite[i];
      }

      calc_bbox(&(cd->BBox), Infinite, 0, numOfInfiniteObjects);

      root->Node[0] = (BBOX_TREE *)cd;

      calc_bbox(&(root->BBox), root->Node, 0, root->Entries);

      /* Root and first node are infinite. */

      root->Infinite = true;

      root->Node[0]->Infinite = true;
    }
  }
  else
  {
    /*
     * There are no finite objects and no Root was created.
     * Create it now and put all infinite objects into it.
     */

    if (numOfInfiniteObjects > 0)
    {
      cd = create_bbox_node(numOfInfiniteObjects);

      for (i = 0; i < numOfInfiniteObjects; i++)
      {
        cd->Node[i] = Infinite[i];
      }

      calc_bbox(&(cd->BBox), Infinite, 0, numOfInfiniteObjects);

      *Root = (BBOX_TREE *)cd;

      (*Root)->Infinite = true;
    }
  }
}
Exemple #16
0
UCS2 *Parser::String_Literal_To_UCS2(const std::string& str)
{
    UCS2 *char_string = nullptr;
    UCS2 *char_array = nullptr;
    std::string::size_type char_array_size = 0;
    int utf8arraysize = 0;
    unsigned char *utf8array = nullptr;
    int index_in = 0;
    int index_out = 0;
    char buffer[8];
    char *dummy_ptr = nullptr;
    int i = 0;

    if(str.length() == 0)
    {
        char_string = reinterpret_cast<UCS2 *>(POV_MALLOC(sizeof(UCS2), "UCS2 String"));
        char_string[0] = 0;

        return char_string;
    }

    char_array_size = str.length();
    char_array = reinterpret_cast<UCS2 *>(POV_MALLOC(char_array_size * sizeof(UCS2), "Character Array"));
    for(i = 0; i < char_array_size; i++)
    {
        if(sceneData->EffectiveLanguageVersion() < 350)
            char_array[i] = (unsigned char)(str[i]);
        else
        {
            char_array[i] = str[i] & 0x007F;
            if(char_array[i] != str[i])
            {
                char_array[i] = ' ';
                PossibleError("Unexpected non-ASCII character has been replaced by space character.");
            }
        }
    }

    char_string = reinterpret_cast<UCS2 *>(POV_MALLOC((char_array_size + 1) * sizeof(UCS2), "UCS2 String"));
    for(index_in = 0, index_out = 0; index_in < char_array_size; index_in++, index_out++)
    {
        if(char_array[index_in] == '\\')
        {
            index_in++;

            switch(char_array[index_in])
            {
                case 'a':
                    char_string[index_out] = 0x07;
                    break;
                case 'b':
                    char_string[index_out] = 0x08;
                    break;
                case 'f':
                    char_string[index_out] = 0x0c;
                    break;
                case 'n':
                    char_string[index_out] = 0x0a;
                    break;
                case 'r':
                    char_string[index_out] = 0x0d;
                    break;
                case 't':
                    char_string[index_out] = 0x09;
                    break;
                case 'v':
                    char_string[index_out] = 0x0b;
                    break;
                case '\0':
                    // [CLi] shouldn't happen, as having a backslash as the last character of a string literal would invalidate the string terminator
                    Error("Unexpected end of escape sequence in text string.");
                    break;
                case '\'':
                case '\"':
                case '\\':
                    char_string[index_out] = char_array[index_in];
                    break;
                case 'u':
                    if(index_in + 4 >= char_array_size)
                        Error("Unexpected end of escape sequence in text string.");

                    buffer[0] = char_array[++index_in];
                    buffer[1] = char_array[++index_in];
                    buffer[2] = char_array[++index_in];
                    buffer[3] = char_array[++index_in];
                    buffer[4] = 0;

                    char_string[index_out] = (UCS2)std::strtoul(buffer, &dummy_ptr, 16);
                    break;
                default:
                    char_string[index_out] = char_array[index_in];
                    POV_FREE(char_array);
                    char_array = nullptr;
                    Error( "Illegal escape sequence in string." );
                    break;
            }
        }
        else
            char_string[index_out] = char_array[index_in];
    }

    char_string[index_out] = 0;
    index_out++;

    char_string = reinterpret_cast<UCS2 *>(POV_REALLOC(char_string, index_out * sizeof(UCS2), "UCS2 String"));

    if (char_array != nullptr)
        POV_FREE(char_array);

    return char_string;
}
Exemple #17
0
UCS2 *Parser::String_Literal_To_UCS2(const char *str, bool pathname)
{
    UCS2 *char_string = NULL;
    UCS2 *char_array = NULL;
    int char_array_size = 0;
    int utf8arraysize = 0;
    unsigned char *utf8array = NULL;
    int index_in = 0;
    int index_out = 0;
    char buffer[8];
    char *dummy_ptr = NULL;
    int i = 0;

    if(strlen(str) == 0)
    {
        char_string = reinterpret_cast<UCS2 *>(POV_MALLOC(sizeof(UCS2), "UCS2 String"));
        char_string[0] = 0;

        return char_string;
    }

    switch(sceneData->stringEncoding)
    {
        case kStringEncoding_ASCII:
            char_array_size = (int)strlen(str);
            char_array = reinterpret_cast<UCS2 *>(POV_MALLOC(char_array_size * sizeof(UCS2), "Character Array"));
            for(i = 0; i < char_array_size; i++)
            {
                if(sceneData->EffectiveLanguageVersion() < 350)
                    char_array[i] = (unsigned char)(str[i]);
                else
                {
                    char_array[i] = str[i] & 0x007F;
                    if(char_array[i] != str[i])
                    {
                        char_array[i] = ' ';
                        PossibleError("Non-ASCII character has been replaced by space character.");
                    }
                }
            }
            break;
        case kStringEncoding_UTF8:
            char_array = Convert_UTF8_To_UCS2(reinterpret_cast<const unsigned char *>(str), (int)strlen(str), &char_array_size);
            break;
        case kStringEncoding_System:
            char_array = POV_CONVERT_TEXT_TO_UCS2(reinterpret_cast<const unsigned char *>(str), strlen(str), &char_array_size);
            if(char_array == NULL)
                Error("Cannot convert system specific text format to Unicode.");
            break;
        default:
            Error("Unsupported text encoding format.");
            break;
    }

    if(char_array == NULL)
        Error("Cannot convert text to UCS2 format.");

    char_string = reinterpret_cast<UCS2 *>(POV_MALLOC((char_array_size + 1) * sizeof(UCS2), "UCS2 String"));
    for(index_in = 0, index_out = 0; index_in < char_array_size; index_in++, index_out++)
    {
        if((char_array[index_in] == '\\') && (sceneData->EffectiveLanguageVersion() >= 371 || !pathname))
        {
            // Historically, escape sequences were ignored when parsing for a filename.
            // As of POV-Ray 3.71, this has been changed.

#if (FILENAME_SEPARATOR == '\\')
            if (pathname)
            {
                Warning("Backslash encountered while parsing for a filename."
                        " As of version 3.71, this is interpreted as an escape sequence just like in any other string literal."
                        " If this is supposed to be a path separator, use a forward slash instead.");
            }
#endif

            index_in++;

            switch(char_array[index_in])
            {
                case 'a':
                    char_string[index_out] = 0x07;
                    break;
                case 'b':
                    char_string[index_out] = 0x08;
                    break;
                case 'f':
                    char_string[index_out] = 0x0c;
                    break;
                case 'n':
                    char_string[index_out] = 0x0a;
                    break;
                case 'r':
                    char_string[index_out] = 0x0d;
                    break;
                case 't':
                    char_string[index_out] = 0x09;
                    break;
                case 'v':
                    char_string[index_out] = 0x0b;
                    break;
                case '\0':
                    // [CLi] shouldn't happen, as having a backslash as the last character of a string literal would invalidate the string terminator
                    Error("Unexpected end of escape sequence in text string.");
                    break;
                case '\'':
                case '\"':
                case '\\':
                    char_string[index_out] = char_array[index_in];
                    break;
                case 'u':
                    if(index_in + 4 >= char_array_size)
                        Error("Unexpected end of escape sequence in text string.");

                    buffer[0] = char_array[++index_in];
                    buffer[1] = char_array[++index_in];
                    buffer[2] = char_array[++index_in];
                    buffer[3] = char_array[++index_in];
                    buffer[4] = 0;

                    char_string[index_out] = (UCS2)strtoul(buffer, &dummy_ptr, 16);
                    break;
                default:
                    char_string[index_out] = char_array[index_in];
                    if ( char_array )
                        POV_FREE(char_array);
                    char_array = NULL;
                    Error( "Illegal escape sequence in string." );
                    break;
            }
        }
        else
        {
            if ((char_array[index_in] == '\\') && pathname)
            {
                // Historically, escape sequences were ignored when parsing for a filename.
                // As of POV-Ray 3.71, this has been changed.

#if (FILENAME_SEPARATOR == '\\')
                Warning("Backslash encountered while parsing for a filename."
                        " In legacy (pre-3.71) scenes, this is NOT interpreted as the start of an escape sequence."
                        " However, for future compatibility it is recommended to use a forward slash as path separator instead.");
#else
                Warning("Backslash encountered while parsing for a filename."
                        " In legacy (pre-3.71) scenes, this is NOT interpreted as the start of an escape sequence.");
#endif
            }

            char_string[index_out] = char_array[index_in];
        }
    }

    char_string[index_out] = 0;
    index_out++;

    char_string = reinterpret_cast<UCS2 *>(POV_REALLOC(char_string, index_out * sizeof(UCS2), "UCS2 String"));

    if(char_array != NULL)
        POV_FREE(char_array);

    return char_string;
}
Exemple #18
0
DBL POVFPU_RunDefault(FUNCTION fn)
{
	StackFrame *pstack = POVFPU_Current_Context->pstackbase;
	DBL *dblstack = POVFPU_Current_Context->dblstackbase;
	unsigned int maxdblstacksize = POVFPU_Current_Context->maxdblstacksize;
	DBL r0, r1, r2, r3, r4, r5, r6, r7;
	Instruction *program = NULL;
	unsigned int k = 0;
	unsigned int pc = 0;
	unsigned int ccr = 0;
	unsigned int sp = 0;
	unsigned int psp = 0;

#if (SUPPORT_INTEGER_INSTRUCTIONS == 1)
	POV_LONG iA, iB, itemp;
#endif

#if (DEBUG_DEFAULTCPU == 1)
	COUNTER instr;
	Long_To_Counter(POVFPU_Functions[fn].fn.program_size, instr);
	Add_Counter(stats[Ray_Function_VM_Instruction_Est], stats[Ray_Function_VM_Instruction_Est], instr);
#endif

	Increase_Counter(stats[Ray_Function_VM_Calls]);

	program = POVFPU_Functions[fn].fn.program;

	while(true)
	{
		k = GET_K(program[pc]);
		switch(GET_OP(program[pc]))
		{
			OP_MATH_AOP(0,+);           // add   Rs, Rd
			OP_MATH_AOP(1,-);           // sub   Rs, Rd
			OP_MATH_AOP(2,*);           // mul   Rs, Rd
			OP_MATH_AOP(3,/);           // div   Rs, Rd
			OP_MOD_A(4);                // mod   Rs, Rd

			OP_ASSIGN_ABOP(5,0,r0);     // move  R0, Rd
			OP_ASSIGN_ABOP(5,1,r1);     // move  R1, Rd
			OP_ASSIGN_ABOP(5,2,r2);     // move  R2, Rd
			OP_ASSIGN_ABOP(5,3,r3);     // move  R3, Rd
			OP_ASSIGN_ABOP(5,4,r4);     // move  R4, Rd
			OP_ASSIGN_ABOP(5,5,r5);     // move  R5, Rd
			OP_ASSIGN_ABOP(5,6,r6);     // move  R6, Rd
			OP_ASSIGN_ABOP(5,7,r7);     // move  R7, Rd

			OP_CMP_ABC(6,0,r0);         // cmp   R0, Rd
			OP_CMP_ABC(6,1,r1);         // cmp   R1, Rd
			OP_CMP_ABC(6,2,r2);         // cmp   R2, Rd
			OP_CMP_ABC(6,3,r3);         // cmp   R3, Rd
			OP_CMP_ABC(6,4,r4);         // cmp   R4, Rd
			OP_CMP_ABC(6,5,r5);         // cmp   R5, Rd
			OP_CMP_ABC(6,6,r6);         // cmp   R6, Rd
			OP_CMP_ABC(6,7,r7);         // cmp   R7, Rd

			OP_ASSIGN_ABOP(7,0,-r0);    // neg   R0, Rd
			OP_ASSIGN_ABOP(7,1,-r1);    // neg   R1, Rd
			OP_ASSIGN_ABOP(7,2,-r2);    // neg   R2, Rd
			OP_ASSIGN_ABOP(7,3,-r3);    // neg   R3, Rd
			OP_ASSIGN_ABOP(7,4,-r4);    // neg   R4, Rd
			OP_ASSIGN_ABOP(7,5,-r5);    // neg   R5, Rd
			OP_ASSIGN_ABOP(7,6,-r6);    // neg   R6, Rd
			OP_ASSIGN_ABOP(7,7,-r7);    // neg   R7, Rd

			OP_ABS_A(8);                // abs   Rs, Rd

			OP_MATH_ABCOP(9,0,POVFPU_Consts[k],+);      // addi  k, Rd
			OP_MATH_ABCOP(9,1,POVFPU_Consts[k],-);      // subi  k, Rd
			OP_MATH_ABCOP(9,2,POVFPU_Consts[k],*);      // muli  k, Rd
			OP_MATH_ABCOP(9,3,POVFPU_Consts[k],/);      // divi  k, Rd
			OP_MOD_ABC(9,4,POVFPU_Consts[k]);           // modi  k, Rd
			OP_ASSIGN_ABOP(9,5,POVFPU_Consts[k]);       // loadi k, Rd

			OP_CMP_ABC(9,6,POVFPU_Consts[k]);           // cmpi  k, Rs

			OP_ASSIGN_ABOP(10,0,ccr == 1);              // seq   Rd
			OP_ASSIGN_ABOP(10,1,ccr != 1);              // sne   Rd
			OP_ASSIGN_ABOP(10,2,ccr == 2);              // slt   Rd
			OP_ASSIGN_ABOP(10,3,ccr >= 1);              // sle   Rd
			OP_ASSIGN_ABOP(10,4,ccr == 0);              // sgt   Rd
			OP_ASSIGN_ABOP(10,5,ccr <= 1);              // sge   Rd
			OP_MATH_ABCOP(10,6,0.0,==);                 // teq   Rd
			OP_MATH_ABCOP(10,7,0.0,!=);                 // tne   Rd

			OP_ASSIGN_ABOP(11,0,POVFPU_Globals[k]);     // load  0(k), Rd
			OP_ASSIGN_ABOP(11,1,dblstack[sp+k]);        // load  SP(k), Rd

			OP_REVASSIGN_ABOP(12,0,POVFPU_Globals[k]);  // store Rs, 0(k)
			OP_REVASSIGN_ABOP(12,1,dblstack[sp+k]);     // store Rs, SP(k)

			OP_SPECIAL(13,0,0,if(ccr == 1) pc = k - 1); // beq   k
			OP_SPECIAL(13,1,0,if(ccr != 1) pc = k - 1); // bne   k
			OP_SPECIAL(13,2,0,if(ccr == 2) pc = k - 1); // blt   k
			OP_SPECIAL(13,3,0,if(ccr >= 1) pc = k - 1); // ble   k
			OP_SPECIAL(13,4,0,if(ccr == 0) pc = k - 1); // bgt   k
			OP_SPECIAL(13,5,0,if(ccr <= 1) pc = k - 1); // bge   k

			OP_XCC_ABOP(14,0,==);                       // xeq   Rd
			OP_XCC_ABOP(14,1,!=);                       // xne   Rd
			OP_XCC_ABOP(14,2,<);                        // xlt   Rd
			OP_XCC_ABOP(14,3,<=);                       // xle   Rd
			OP_XCC_ABOP(14,4,>);                        // xgt   Rd
			OP_XCC_ABOP(14,5,>=);                       // xge   Rd

			OP_SPECIAL(14,6,0,if((r0 == 0.0) && (r0 == 0.0)) POVFPU_Exception(fn)); // xdz   R0, R0
			OP_SPECIAL(14,6,1,if((r0 == 0.0) && (r1 == 0.0)) POVFPU_Exception(fn)); // xdz   R0, R1
			OP_SPECIAL(14,6,2,if((r0 == 0.0) && (r2 == 0.0)) POVFPU_Exception(fn)); // xdz   R0, R2
			OP_SPECIAL(14,6,3,if((r0 == 0.0) && (r3 == 0.0)) POVFPU_Exception(fn)); // xdz   R0, R3
			OP_SPECIAL(14,6,4,if((r0 == 0.0) && (r4 == 0.0)) POVFPU_Exception(fn)); // xdz   R0, R4
			OP_SPECIAL(14,6,5,if((r0 == 0.0) && (r5 == 0.0)) POVFPU_Exception(fn)); // xdz   R0, R5
			OP_SPECIAL(14,6,6,if((r0 == 0.0) && (r6 == 0.0)) POVFPU_Exception(fn)); // xdz   R0, R6
			OP_SPECIAL(14,6,7,if((r0 == 0.0) && (r7 == 0.0)) POVFPU_Exception(fn)); // xdz   R0, R7

			OP_SPECIAL_CASE(15,0,0)                     // jsr   k
				pstack[psp].pc = pc;
				pstack[psp].fn = fn;
				psp++;
				if(psp >= MAX_CALL_STACK_SIZE)
					POVFPU_Exception(fn, "Maximum function evaluation recursion level reached.");
				pc = k;
				continue; // prevent increment of pc
			OP_SPECIAL_CASE(15,0,1)                     // jmp   k
				pc = k;
				continue; // prevent increment of pc
			OP_SPECIAL_CASE(15,0,2)                     // rts
				if(psp == 0)
					return r0;
				psp--;
				pc = pstack[psp].pc; // old position, will be incremented
				fn = pstack[psp].fn;
				program = POVFPU_Functions[fn].fn.program;
				break;
			OP_SPECIAL_CASE(15,0,3)                     // call  k
				pstack[psp].pc = pc;
				pstack[psp].fn = fn;
				psp++;
				if(psp >= MAX_CALL_STACK_SIZE)
					POVFPU_Exception(fn, "Maximum function evaluation recursion level reached.");
				fn = k;
				program = POVFPU_Functions[fn].fn.program;
				pc = 0;
				continue; // prevent increment of pc

			OP_SPECIAL_CASE(15,0,4)                     // sys1  k
				r0 = POVFPU_Sys1Table[k](r0);
				break;
			OP_SPECIAL_CASE(15,0,5)                     // sys2  k
				r0 = POVFPU_Sys2Table[k](r0,r1);
				break;
			OP_SPECIAL_CASE(15,0,6)                     // trap  k
				r0 = POVFPU_TrapTable[k].fn(&dblstack[sp], fn);
				maxdblstacksize = POVFPU_Current_Context->maxdblstacksize;
				dblstack = POVFPU_Current_Context->dblstackbase;
				break;
			OP_SPECIAL_CASE(15,0,7)                     // traps k
				POVFPU_TrapSTable[k].fn(&dblstack[sp], fn, sp);
				maxdblstacksize = POVFPU_Current_Context->maxdblstacksize;
				dblstack = POVFPU_Current_Context->dblstackbase;
				break;

			OP_SPECIAL_CASE(15,1,0)                     // grow  k
				if((unsigned int)((unsigned int)sp + (unsigned int)k) >= (unsigned int)MAX_K)
				{
					POVFPU_Exception(fn, "Stack full. Possible infinite recursive function call.");
				}
				else if(sp + k >= maxdblstacksize)
				{
					maxdblstacksize = POVFPU_Current_Context->maxdblstacksize = POVFPU_Current_Context->maxdblstacksize + max(k + 1, (unsigned int)256);
					dblstack = POVFPU_Current_Context->dblstackbase = (DBL *)POV_REALLOC(dblstack, sizeof(DBL) * maxdblstacksize, "fn: stack");
				}
				break;
			OP_SPECIAL_CASE(15,1,1)                     // push  k
				if(sp + k >= maxdblstacksize)
					POVFPU_Exception(fn, "Function evaluation stack overflow.");
				sp += k;
				break;
			OP_SPECIAL_CASE(15,1,2)                     // pop   k
				if(k > sp)
					POVFPU_Exception(fn, "Function evaluation stack underflow.");
				sp -= k;
				break;
#if (SUPPORT_INTEGER_INSTRUCTIONS == 1)
			OP_SPECIAL_CASE(15,1,3)                     // iconv
				iA = POV_LONG(r0);
				break;
			OP_SPECIAL_CASE(15,1,4)                     // fconv
				r0 = DBL(iA);
				break;

			OP_SPECIAL_CASE(15,1,5)                     // reserved
				POVFPU_Exception(fn, "Internal error - reserved function VM opcode found!");
				break;

			OP_INT_MATH_ABOP(15,32,+);                  // add   s, d
			OP_INT_MATH_ABOP(15,33,-);                  // sub   s, d
			OP_INT_MATH_ABOP(15,34,*);                  // mul   s, d
			OP_INT_SPECIAL(15,35,0,iA = iA / iB);       // div   B, A
			OP_INT_SPECIAL(15,35,1,iB = iB / iA);       // div   A, B
			OP_INT_SPECIAL(15,35,2,iA = iA % iB);       // mod   B, A
			OP_INT_SPECIAL(15,35,3,iB = iB % iA);       // mod   A, B

			OP_INT_SPECIAL(15,36,0,ccr = (((iB > iA) & 1) << 1) | ((iB == iA) & 1)); // cmp   B, A
			OP_INT_SPECIAL(15,36,1,ccr = (((iA > iB) & 1) << 1) | ((iA == iB) & 1)); // cmp   A, B

			OP_INT_SPECIAL(15,36,2,itemp = iA; iA = iB; iB = itemp); // exg   A, B

			OP_INT_SPECIAL(15,36,3,iA = iB = 0);        // clr   A, B
			OP_INT_SPECIAL(15,37,0,iA = 0);             // clr   A
			OP_INT_SPECIAL(15,37,1,iB = 0);             // clr   B

			OP_INT_SPECIAL(15,37,2,iA = iB);            // move  B, A
			OP_INT_SPECIAL(15,37,3,iB = iA);            // move  A, B

			OP_INT_SPECIAL(15,38,0,iA = -iA);           // neg   A
			OP_INT_SPECIAL(15,38,1,iB = -iB);           // neg   B

			OP_INT_SPECIAL(15,38,2,iA = abs(iA));       // abs   A
			OP_INT_SPECIAL(15,38,3,iB = abs(iB));       // abs   B

			OP_INT_SPECIAL(15,39,0,iA = iA + k);        // addi  k, A
			OP_INT_SPECIAL(15,39,1,iB = iB + k);        // addi  k, B
			OP_INT_SPECIAL(15,39,2,iA = iA - k);        // subi  k, A
			OP_INT_SPECIAL(15,39,3,iB = iB - k);        // subi  k, B

			OP_INT_MATH_SHIFT_ABOP(15,40,<<,POV_LONG);     // asl   s, d
			OP_INT_MATH_SHIFT_ABOP(15,41,>>,POV_LONG);     // asr   s, d
			OP_INT_MATH_SHIFT_ABOP(15,42,<<,POV_ULONG);    // lsl   s, d
			OP_INT_MATH_SHIFT_ABOP(15,43,>>,POV_ULONG);    // lsr   s, d

			OP_INT_MATH_ABOP(15,44,&);                  // and   s, d
			OP_INT_MATH_ABOP(15,45,|);                  // or    s, d
			OP_INT_MATH_ABOP(15,46,^);                  // xor   s, d
			OP_INT_SPECIAL(15,47,0,iA = !iA);           // not   A, A
			OP_INT_SPECIAL(15,47,1,iA = !iB);           // not   B, A
			OP_INT_SPECIAL(15,47,2,iB = !iA);           // not   A, B
			OP_INT_SPECIAL(15,47,3,iB = !iB);           // not   B, B

			OP_INT_SPECIAL(15,48,0,iA = k);             // loadi A
			OP_INT_SPECIAL(15,48,1,iB = k);             // loadi B
			OP_INT_SPECIAL(15,48,2,iA = (iA << 16) | k);// ldhi  A
			OP_INT_SPECIAL(15,48,3,iB = (iB << 16) | k);// ldhi  B

			OP_INT_SPECIAL(15,49,0,iA = max(POV_LONG(k), iA)); // max   k, A
			OP_INT_SPECIAL(15,49,1,iB = max(POV_LONG(k), iB)); // max   k, B
			OP_INT_SPECIAL(15,49,2,iA = min(POV_LONG(k), iA)); // min   k, A
			OP_INT_SPECIAL(15,49,3,iB = min(POV_LONG(k), iB)); // min   k, B

			OP_INT_SPECIAL(15,50,0,iA = (POV_LONG(iA) << k));  // asl   k, A
			OP_INT_SPECIAL(15,50,1,iB = (POV_LONG(iB) >> k));  // asr   k, B
			OP_INT_SPECIAL(15,50,2,iA = (POV_ULONG(iA) << k)); // lsl   k, A
			OP_INT_SPECIAL(15,50,3,iB = (POV_ULONG(iB) >> k)); // lsr   k, B
#endif
			default:                                    // nop
				break;
		}

		pc++;
	}

#if (DEBUG_DEFAULTCPU == 1)
	printf("Registers\n");
	printf("=========\n");
	printf("PC = %d\n", (int)pc);
	printf("CCR = %x\n", (int)ccr);
	printf("R0 = %8f   R4 = %8f\n", (float)r0, (float)r4);
	printf("R1 = %8f   R5 = %8f\n", (float)r1, (float)r5);
	printf("R2 = %8f   R6 = %8f\n", (float)r2, (float)r6);
	printf("R3 = %8f   R7 = %8f\n", (float)r3, (float)r7);
#endif
}
Exemple #19
0
int sort_and_split(BBOX_TREE **Root, BBOX_TREE **&Finite, size_t *numOfFiniteObjects, ptrdiff_t first, ptrdiff_t last, size_t& maxfinitecount)
{
    BBOX_TREE *cd;
    ptrdiff_t size, i, best_loc;
    DBL *area_left, *area_right;
    DBL best_index, new_index;

    int Axis = find_axis(Finite, first, last);
    size = last - first;
    if(size <= 0)
        return (1);

    // Actually, we could do this faster in several ways. We could use a
    // logn algorithm to find the median along the given axis, and then a
    // linear algorithm to partition along the axis. Oh well.

    switch(Axis)
    {
        case X:
            QSORT(reinterpret_cast<void *>(&Finite[first]), size, sizeof(BBOX_TREE *), compboxes<X>);
            break;
        case Y:
            QSORT(reinterpret_cast<void *>(&Finite[first]), size, sizeof(BBOX_TREE *), compboxes<Y>);
            break;
        case Z:
            QSORT(reinterpret_cast<void *>(&Finite[first]), size, sizeof(BBOX_TREE *), compboxes<Z>);
            break;
    }

    // area_left[] and area_right[] hold the surface areas of the bounding
    // boxes to the left and right of any given point. E.g. area_left[i] holds
    // the surface area of the bounding box containing Finite 0 through i and
    // area_right[i] holds the surface area of the box containing Finite
    // i through size-1.

    area_left  = new DBL[size];
    area_right = new DBL[size];

    // Precalculate the areas for speed.
    build_area_table(Finite, first, last - 1, area_left);
    build_area_table(Finite, last - 1, first, area_right);
    best_index = area_right[0] * (size - 3.0);
    best_loc = -1;

    // Find the most effective point to split. The best location will be
    // the one that minimizes the function N1*A1 + N2*A2 where N1 and N2
    // are the number of objects in the two groups and A1 and A2 are the
    // surface areas of the bounding boxes of the two groups.

    for(i = 0; i < size - 1; i++)
    {
        new_index = (i + 1) * area_left[i] + (size - 1 - i) * area_right[i + 1];

        if(new_index < best_index)
        {
            best_index = new_index;
            best_loc = i + first;
        }
    }

    delete[] area_left;
    delete[] area_right;

    // Stop splitting if the BUNCHING_FACTOR is reached or
    // if splitting stops being effective.
    if((size <= BUNCHING_FACTOR) || (best_loc < 0))
    {
        cd = create_bbox_node(size);

        for(i = 0; i < size; i++)
            cd->Node[i] = Finite[first+i];

        calc_bbox(&(cd->BBox), Finite, first, last);
        *Root = cd;
        if(*numOfFiniteObjects >= maxfinitecount)
        {
            // Prim array overrun, increase array by 50%.
            maxfinitecount = 1.5 * maxfinitecount;

            // For debugging only.
            // TODO MESSAGE      Debug_Info("Reallocing Finite to %d\n", maxfinitecount);
            Finite = reinterpret_cast<BBOX_TREE **>(POV_REALLOC(Finite, maxfinitecount * sizeof(BBOX_TREE *), "bounding boxes"));
        }

        Finite[*numOfFiniteObjects] = cd;
        (*numOfFiniteObjects)++;

        return (1);
    }

    sort_and_split(Root, Finite, numOfFiniteObjects, first, best_loc + 1, maxfinitecount);
    sort_and_split(Root, Finite, numOfFiniteObjects, best_loc + 1, last, maxfinitecount);

    return (0);
}