// // Initialize the terrain LOD structures // // Allocates the height/variance arrays // Fills in the arrays with initial values // // fZScale converts from height values (meters) to world coordinates // DTErr SMTerrain::Init(const vtElevationGrid *pGrid, float fZScale) { DTErr err = BasicInit(pGrid); if (err != DTErr_OK) return err; if (m_iColumns != m_iRows) return DTErr_NOTSQUARE; // get size of array m_iDim = m_iColumns; // compute n (log2 of grid size) m_n = vt_log2(m_iDim - 1); // ensure that the grid is size (1 << n) + 1 int required_size = (1<<m_n) + 1; if (m_iColumns != required_size || m_iRows != required_size) return DTErr_NOTPOWER2; // the triangle bintree will have (2n + 2) levels // these levels are numbered with 1-based numbering, (1 2 3...) m_iLevels = 2 * m_n + 2; // Default: create 8x8 blocks (eg. 1024 -> 128*128 (actually, 129)) m_iBlockN = m_n - 3; // 8x8 blocks // safety check if (m_iBlockN < 0) m_iBlockN = 0; m_iBlockLevel = 2 * (m_n - m_iBlockN) + 1; m_iBlockCutoff = 1 << (2 * (m_n - m_iBlockN)); m_iBlockArrayDim = 1 << (m_n - m_iBlockN); // Allocate a 2D array of blocks int i, j; m_pBlockArray = new BlockPtr[m_iBlockArrayDim]; for (i = 0; i < m_iBlockArrayDim; i++) m_pBlockArray[i] = new Block[m_iBlockArrayDim]; // the triangle bintree will have ((1 << levels) - 1) nodes m_iNodes = (1 << m_iLevels) - 1; // the bottom level of the bintree cannot be split m_iSplitCutoff = (1 << (m_iLevels-2)); #if !ASSUME_LOWEST_LEVEL // however, we don't need to store variance for the bottom-most nodes // of the tree, so use one less level, and add 1 for 1-based numbering m_iUsedNodes = (1 << (m_iLevels-1)); #else // APPROXIMATION // Seumas says he gets away with levels-4 !! Let's try a less // radical approximation: levels-2 m_iUsedNodes = (1 << (m_iLevels-2)); #endif // allocate arrays m_pData = new HeightType[m_iColumns * m_iRows]; // this is potentially a big chunk of memory, so it may fail if (!m_pData) return DTErr_NOMEM; // copy data from supplied elevation grid float elev; for (i = 0; i < m_iColumns; i++) { for (j = 0; j < m_iRows; j++) { elev = pGrid->GetFValue(i, j); m_pData[offset(i,j)] = (HeightType)(PACK_SCALE * elev); } } m_fZScale = fZScale / PACK_SCALE; // find indices of corner vertices m_sw = offset(0, 0); m_nw = offset(0, m_iRows-1); m_ne = offset(m_iColumns-1, m_iRows-1); m_se = offset(m_iColumns-1, 0); m_iPolygonTarget = DEFAULT_POLYGON_TARGET; m_fQualityConstant= 0.1f; // safe initial value m_iDrawnTriangles = -1; hack_detail_pass = false; return DTErr_OK; }
int mdlInitialize(MDL *pmdl,char **argv,void (*fcnChild)(MDL)) { MDL mdl,tmdl; int i,nThreads,bThreads,bDiag; char *p,ach[256],achDiag[256]; *pmdl = NULL; /* ** Do some low level argument parsing for number of threads, and ** diagnostic flag! */ bDiag = 0; bThreads = 0; i = 1; while (argv[i]) { if (!strcmp(argv[i],"-sz") && !bThreads) { ++i; if (argv[i]) { nThreads = atoi(argv[i]); bThreads = 1; } } if (!strcmp(argv[i],"+d") && !bDiag) { p = getenv("MDL_DIAGNOSTIC"); if (!p) p = getenv("HOME"); if (!p) sprintf(ach,"/tmp"); else sprintf(ach,"%s",p); bDiag = 1; } ++i; } if (!bThreads) { nThreads = pthread_procsetinfo(NULL,0); } mdl = malloc(sizeof(struct mdlContext)); assert(mdl != NULL); mdl->pmdl = malloc(nThreads*sizeof(MDL)); assert(mdl->pmdl != NULL); mdl->pmdl[0] = mdl; /* that's me! */ mdl->pt = (pthread_t *)malloc(nThreads*sizeof(pthread_t)); assert(mdl->pt != NULL); /* ** Initialize caching barrier. */ pthread_barrier_init(&mdl->bar,pthread_barrierattr_default,nThreads); *pmdl = mdl; if (nThreads > 1) { for (i=1;i<nThreads;++i) { /* ** Allocate the children mdl data structures. */ tmdl = malloc(sizeof(struct mdlContext)); assert(tmdl != NULL); mdl->pmdl[i] = tmdl; tmdl->pt = NULL; } for (i=0;i<nThreads;++i) { /* ** Set up all the mdl data structures. */ tmdl = mdl->pmdl[i]; BasicInit(tmdl); tmdl->pmdl = mdl->pmdl; tmdl->idSelf = i; tmdl->bDiag = bDiag; tmdl->nThreads = nThreads; if (tmdl->bDiag) { sprintf(achDiag,"%s.%d",ach,tmdl->idSelf); tmdl->fpDiag = fopen(achDiag,"w"); assert(tmdl->fpDiag != NULL); } } for (i=1;i<nThreads;++i) { /* ** Start all the children. */ pthread_create(&mdl->pt[i],pthread_attr_default,fcnChild, mdl->pmdl[i]); } return(nThreads); } else { /* ** A unik! */ BasicInit(mdl); mdl->bDiag = bDiag; mdl->nThreads = 1; mdl->idSelf = 0; if (mdl->bDiag) { sprintf(achDiag,"%s.%d",ach,mdl->idSelf); mdl->fpDiag = fopen(achDiag,"w"); assert(mdl->fpDiag != NULL); } return(nThreads); } }