#include #include #include #include #include "AS3.h" typedef enum { FALSE, TRUE } boolean; int resX, resY, nodeDistance, terrainWidth, terrainHeight; float* buffer; int* nodes; int* path; unsigned int* terrain; int useTerrain = 0; AS3_Val initializeBuffers(void* self, AS3_Val args) { int i, cols, rows, alloc; AS3_ArrayValue(args, "IntType, IntType, IntType", &resX, &resY, &nodeDistance); buffer = malloc(resX*resY*sizeof(float)*3); cols = (int)floor(resX/nodeDistance); rows = (int)floor(resY/nodeDistance); alloc = cols*rows*sizeof(int)*4; nodes = malloc(alloc); for (i=0; i 0) ? p : 0; } AS3_Val createNodes(void* self, AS3_Val args) { int colMultiplier, rowMultiplier, i, i3, value, col, row, n, acc; int len = resX*resY; AS3_ArrayValue(args, "IntType, IntType", &colMultiplier, &rowMultiplier); for (i=0; i 0) && (value < 32)) { n = initNode(col, row, TRUE); acc = nodes[n+3]; switch (value) { case 1: //if (getBitFlagAt(6, n)) { remBitFlagAt(6, n); remBitFlagAt(2, initNode(col, (row+1), TRUE)); //} break; case 2: //if (getBitFlagAt(4, n)) { remBitFlagAt(4, n); remBitFlagAt(0, initNode((col+1), row, TRUE)); //} break; case 4: //if (getBitFlagAt(5, n)) { remBitFlagAt(5, n); remBitFlagAt(1, initNode((col+1), (row+1), TRUE)); //} break; case 8: //if (getBitFlagAt(7, n)) { remBitFlagAt(7, n); remBitFlagAt(3, initNode((col-1), (row+1), TRUE)); //} break; case 16: remBitFlagAt(5, n); remBitFlagAt(1, initNode((col+1), (row+1), TRUE)); remBitFlagAt(7, initNode((col+1), row, TRUE)); remBitFlagAt(3, initNode(col, (row+1), TRUE)); break; } } } return 0; } AS3_Val getOptimalPath(void* self, AS3_Val args) { int startNodeCol, startNodeRow, goalNodeCol, goalNodeRow, i, j, k, terrainCorrection, n, m; int cols = (int)floor(resX/nodeDistance); int rows = (int)floor(resY/nodeDistance); int len = cols*rows; int openSet[len]; int closedSet[len]; int newOpenSet[len]; AS3_ArrayValue(args, "IntType, IntType, IntType, IntType", &startNodeCol, &startNodeRow, &goalNodeCol, &goalNodeRow); int dx = goalNodeCol-startNodeCol; int dy = goalNodeRow-startNodeRow; n = (int)(4*(startNodeCol+startNodeRow*(int)floor(resX/nodeDistance))); openSet[0] = n; int lnOpenSet = 1; int lnClosedSet = 0; int o = 4*len; const float SQRT2 = 1.4142135623730950488016887242097; float gx[o]; float fx[o]; float hx[o]; float tv; int nNodes[8]; int parents[o]; gx[n] = 0; hx[n] = fx[n] = sqrt(dx*dx+dy*dy)*((useTerrain == 1) ? getTerrainValue(startNodeCol, startNodeRow) : 1); for (i=0; i<2*len; i++) { gx[i] = 0; hx[i] = 0; fx[i] = 0; parents[i] = -1; } while (lnOpenSet > 0) { float fxMin = -1; for (i=0; i= 0) { q = (int)(n*.25); while ((q >= 0) && (parents[n] >= 0)) { tmpPath[(int)p++] = q; n = parents[n]; q = (int)(n*.25); } q = (int)(4*(startNodeCol+startNodeRow*(int)floor(resX/nodeDistance))*.25); if (q >= 0) { tmpPath[(int)p++] = q; } } free(path); path = malloc((int)(p*sizeof(int))); float fxMax = 0; for (i=0; i fxMax) { fxMax = fx[path[i]*4]; } } AS3_Val retVal = AS3_Array("IntType, DoubleType", (int)(p*sizeof(int)), ((p < 3) ? fxMax*getTerrainValue(goalNodeCol, goalNodeRow) : fxMax)); return retVal; } j = 0; for (i=0; i= -1) && (dx*dy <= 1) && (nodes[i+2] == 1)) { if ((dx == -1) && (dy == 0)) { if ((a0 & (int)pow(2, 0)) > 0) { nNodes[j++] = i; } } else if ((dx == -1) && (dy == -1)) { if ((a0 & (int)pow(2, 1)) > 0) { nNodes[j++] = i; } } else if ((dx == 0) && (dy == -1)) { if ((a0 & (int)pow(2, 2)) > 0) { nNodes[j++] = i; } } else if ((dx == 1) && (dy == -1)) { if ((a0 & (int)pow(2, 3)) > 0) { nNodes[j++] = i; } } else if ((dx == 1) && (dy == 0)) { if ((a0 & (int)pow(2, 4)) > 0) { nNodes[j++] = i; } } else if ((dx == 1) && (dy == 1)) { if ((a0 & (int)pow(2, 5)) > 0) { nNodes[j++] = i; } } else if ((dx == 0) && (dy == 1)) { if ((a0 & (int)pow(2, 6)) > 0) { nNodes[j++] = i; } } else if ((dx == -1) && (dy == 1)) { if ((a0 & (int)pow(2, 7)) > 0) { nNodes[j++] = i; } } } if (j == 8) { break; } } for (i=0; i