void LabEngine::doMap() { static uint16 amigaMapPalette[] = { 0x0BA8, 0x0C11, 0x0A74, 0x0076, 0x0A96, 0x0DCB, 0x0CCA, 0x0222, 0x0444, 0x0555, 0x0777, 0x0999, 0x0AAA, 0x0ED0, 0x0EEE, 0x0694 }; _graphics->_fadePalette = amigaMapPalette; updateEvents(); loadMapData(); _graphics->blackAllScreen(); _interface->attachButtonList(&_mapButtonList); drawMap(_roomNum, _roomNum, _maps[_roomNum]._pageNumber, true); _event->mouseShow(); _graphics->screenUpdate(); processMap(_roomNum); _event->mouseHide(); _interface->attachButtonList(nullptr); _graphics->fade(false); _graphics->blackAllScreen(); _graphics->rectFill(0, 0, _graphics->_screenWidth - 1, _graphics->_screenHeight - 1, 0); freeMapData(); _event->mouseShow(); _graphics->screenUpdate(); }
void gameScreen(gameState &game) { vector<vector<char>> processedMap; processMap("testing.map", processedMap); renderMap(processedMap); game = QUIT_MENU; }
AREXPORT void ArForbiddenRangeDevice::setRobot(ArRobot *robot) { myRobot = robot; if (myRobot != NULL) myRobot->addSensorInterpTask(myName.c_str(), 20, &myProcessCB); ArRangeDevice::setRobot(robot); myMap->lock(); myMap->addMapChangedCB(&myMapChangedCB); processMap(); myMap->unlock(); }
DiscreteDepthDistortionModel SlamCalibrator::calibrate() const { BOOST_ASSERT(!sseqs_.empty()); DiscreteDepthDistortionModel model(sseqs_[0]->proj_.width_, sseqs_[0]->proj_.height_); size_t total_num_training = 0; for(size_t i = 0; i < size(); ++i) { cout << "Accumulating training data for sequence " << i << flush; total_num_training += processMap(*sseqs_[i], trajectories_[i], *maps_[i], &model); } cout << "Trained new DiscreteDepthDistortionModel using " << total_num_training << " training examples." << endl; return model; }
void LevelXmlParser::processLevel(xmlNodePtr cur, Level* level) { xmlNodePtr child = cur->xmlChildrenNode; while (child != NULL) { if (!xmlStrcmp(child->name, (const xmlChar*)"map")) { processMap(child, level); } if (!xmlStrcmp(child->name, (const xmlChar*)"playerstart")) { processPlayerStart(child, level); } child = child->next; } }
bool TMXLoader::Private::load(const char *f) { TinyXML::XMLDocument l_tmx; XMLElement *l_root; is_loaded = false; if (l_tmx.LoadFile(f) != XML_NO_ERROR) return(false); /* get parent directory */ base_directory = Core::Platform::PathDirectory(f); /* parse general map data */ if (!(l_root = l_tmx.RootElement()) || !processMap(*l_root)) return(false); /* parse tilesets */ XMLElement *l_tileset = l_root->FirstChildElement(TMXTILESET_NODE); while (l_tileset) { if (!processTileset(*l_tileset)) return(false); l_tileset = l_tileset->NextSiblingElement(TMXTILESET_NODE); } /* parse layers and object groups */ XMLElement *l_element = l_root->FirstChildElement(); while (l_element) { if (0 == strcmp(l_element->Value(), TMXLAYER_NODE) && !processLayer(*l_element)) return(false); else if (0 == strcmp(l_element->Value(), TMXOBJECTGROUP_NODE) && !processObjectGroup(*l_element)) return(false); l_element = l_element->NextSiblingElement(); } /* attach layers to scene */ Game::SharedSceneLayerList::iterator l_layer_i; for (l_layer_i = layers.begin(); l_layer_i != layers.end(); ++l_layer_i) scene.pushLayer(*l_layer_i); return(is_loaded = true); }
/* * Analyze the given object and set up for contour drawing with VBOs */ int VertBufManager::analyzeConts(Iobj *obj, int obNum, int thickenCont, int checkStipple, int checkTime) { RGBTmap colors; pair<RGBTmap::iterator,bool> mapret; RGBTmap::iterator mapit; DrawProps defProps, contProps; VertBufData *vbd = obj->vertBufCont; RGBTindices rInd; b3dUInt32 contRGBT; Icont *cont; int handleFlags, nonVboFlags, numRemnant, fullState, skip, numVerts, cumInd, co; int numInds, ivert, irem, iDefInd, contState, surfState, ind, pt, psize, match; rInd.numFanInds = 0; handleFlags = CHANGED_COLOR | CHANGED_TRANS; nonVboFlags = CHANGED_3DWIDTH; // Check if there is a current VBO and it is all still valid // TODO: handle finegrain if (vbd && vbd->vbObj && checkStipple == vbd->checkStipple && thickenCont == vbd->thickenCont && checkTime == vbd->checkTime) { match = 1; if (thickenCont) match = checkSelectedAreRemnants(vbd, obNum); if (match && checkStipple) { for (co = 0; co < obj->contsize; co++) { if ((obj->cont[co].flags & ICONT_STIPPLED) && !numberInList(co, vbd->remnantIndList, vbd->numRemnant, 0)) { match = 0; break; } } } if (match && !Imodv->standalone && obNum == Imodv->imod->cindex.object && vbd->checksum != imodObjectChecksum(obj, obNum)) match = 0; if (match) return -1; } istoreDefaultDrawProps(obj, &defProps); numRemnant = 0; cumInd = 0; numVerts = 0; for (co = 0; co < obj->contsize; co++) { cont = &obj->cont[co]; if (!imodvCheckContourDraw(cont, co, checkTime)) continue; setOrClearFlags(&cont->flags, ICONT_TEMPUSE, 0); fullState = istoreContSurfDrawProps(obj->store, &defProps, &contProps, co, cont->surf, &contState, &surfState); // Skip a gap without counting it; count ones to be excluded or that can't be handled skip = 0; if (contProps.gap) continue; if ((thickenCont && imodvCheckThickerContour(co)) || (fullState & nonVboFlags) || (checkStipple && (cont->flags & ICONT_STIPPLED))) skip = 1; // Check for point changes that would need to be handled if (!skip && cont->store) { if (istoreCountItems(cont->store, GEN_STORE_COLOR, 1) || istoreCountItems(cont->store, GEN_STORE_TRANS, 1)) skip = 1; if (!skip && istoreCountItems(cont->store, GEN_STORE_3DWIDTH, 1)) skip = 1; if (!skip && istoreCountItems(cont->store, GEN_STORE_GAP, 1)) skip = 1; } if (skip) { setOrClearFlags(&cont->flags, ICONT_TEMPUSE, 1); numRemnant++; continue; } // Determine the number of indices needed including restart index numVerts += cont->psize; numInds = cont->psize + 1; if (iobjClose(obj->flags) && !(cont->flags & ICONT_OPEN)) numInds++; // For a special contour, add to list of RGBT values with the index count if it // is not on the list; if it is already on the list add to its count; if (fullState & handleFlags) { rInd.firstElement = co; rInd.numInds = numInds; packRGBT(&contProps, 0, contRGBT); mapret = colors.insert(pair<b3dUInt32,RGBTindices>(contRGBT, rInd)); if (mapret.second == false) mapret.first->second.numInds += numInds; } else { cumInd += numInds; } } if (!numVerts) { vbCleanupContVBD(obj); return 2; } vbd = allocateVBDIfNeeded(&obj->vertBufCont); if (!vbd) return 1; // Add up the special set sizes and re-initialize the counts to be starting indexes vbd->numRemnant = numRemnant; co = -1; if (allocateSpecialSets(vbd, colors.size(), cumInd, 0) || processMap(vbd, &colors, cumInd, 1, co)) { vbCleanupContVBD(obj); return 1; } imodTrace('b',"dfltInd %d spec sets %d cumind %d remnant %d", vbd->numIndDefault, vbd->numSpecialSets, cumInd, numRemnant); if (genAndBindBuffers(vbd, numVerts, cumInd) || allocateTempVerts(numVerts) || allocateTempInds(cumInd)) { vbCleanupContVBD(obj); return 1; } // Set properties of this VB packRGBT(&defProps, 0, vbd->defaultRGBT); vbd->checkTime = checkTime; vbd->checkStipple = checkStipple; vbd->thickenCont = thickenCont; vbd->checksum = imodObjectChecksum(obj, obNum); // Load the vertex and index temp arrays ivert = 0; iDefInd = 0; irem = 0; for (co = 0; co < obj->contsize; co++) { cont = &obj->cont[co]; if (!imodvCheckContourDraw(cont, co, checkTime)) continue; fullState = istoreContSurfDrawProps(obj->store, &defProps, &contProps, co, cont->surf, &contState, &surfState); if (contProps.gap) continue; // Add marked contours to the remnant list if (cont->flags & ICONT_TEMPUSE) { setOrClearFlags(&cont->flags, ICONT_TEMPUSE, 0); vbd->remnantIndList[irem++] = co; continue; } // Copy points onto vertex list psize = cont->psize; memcpy(&mVerts[3 * ivert], cont->pts, psize * 3 * sizeof(float)); numInds = psize + 1; if (iobjClose(obj->flags) && !(cont->flags & ICONT_OPEN)) numInds++; // Find index where indices start and increment it if (fullState & handleFlags) { packRGBT(&contProps, 0, contRGBT); mapit = colors.find(contRGBT); ind = mapit->second.numInds; mapit->second.numInds += numInds; } else { ind = iDefInd; iDefInd += numInds; } // Set up indices to all points, add one if closed, add restart index; for (pt = 0; pt < psize; pt++) mInds[ind + pt] = ivert + pt; if (numInds > psize + 1) { mInds[ind + psize] = ivert; mInds[ind + psize + 1] = RESTART_INDEX; } else mInds[ind + psize] = RESTART_INDEX; ivert += psize; } imodTrace('b',"ivert %d numVerts*3 %d idefind %d cumind %d", ivert, numVerts * 3, iDefInd, cumInd); /*for (pt = 0; pt < cumInd; pt++) { imodPrintStderr(" %d", mInds[pt]); if ((pt + 1) % 16 == 0) imodPrintStderr("\n"); } imodPrintStderr("\n"); */ // Transfer to GL b3dBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, cumInd * sizeof(GLuint), mInds); b3dBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); b3dBufferSubData(GL_ARRAY_BUFFER, 0, numVerts * 3 * sizeof(GLfloat), mVerts); b3dBindBuffer(GL_ARRAY_BUFFER, 0); return 0; }
/* * Analyze spherical points in the given object and convert them to vectors and * normals for faster drawing */ int VertBufManager::analyzeSpheres(Iobj *obj, int obNum, float zscale, int xybin, float scrnScale, int quality, int fillType, int useFillColor, int thickenCont, int checkTime) { RGBTmap colors; pair<RGBTmap::iterator,bool> mapret; RGBTmap::iterator mapit; RGBTindices rInd; DrawProps defProps, contProps; b3dUInt32 contRGBT; VertBufData *vbd = obj->vertBufSphere; Icont *cont; int handleFlags, nonVboFlags = 0, numRemnant, fullState, skip, numVerts, co, pt; int colorType, cumFanInd, cumQuadInd, surfState, contState, stepRes; float drawsize; int numDefSphVert, numDefSphQuad, numDefSphFan, numTriples,indVert, indQuad, indFan; int indQuadDef, indFanDef, irem, match; if (fillType > 0) handleFlags = (useFillColor ? CHANGED_FCOLOR : CHANGED_COLOR) | CHANGED_TRANS; else { handleFlags = CHANGED_COLOR | CHANGED_TRANS; nonVboFlags = CHANGED_3DWIDTH; } colorType = useFillColor ? GEN_STORE_FCOLOR : GEN_STORE_COLOR; istoreDefaultDrawProps(obj, &defProps); // Check if there is a current VBO and it is all still valid // TODO: handle finegrain AND size changes //packRGBT(defProps, useFillColor, contRGBT); if (vbd && vbd->vbObj && fillType == vbd->fillType && vbd->useFillColor == useFillColor && quality == vbd->quality && obj->pdrawsize == vbd->pdrawsize && checkTime == vbd->checkTime && fabs((double)(scrnScale - vbd->scrnScale)) < 1.e-4 && fabs((double)(zscale - vbd->zscale)) < 1.e-4 && (fillType != 0 || thickenCont == vbd->thickenCont)) { match = 1; if (fillType == 0 && thickenCont) match = checkSelectedAreRemnants(vbd, obNum); if (match && !Imodv->standalone && obNum == Imodv->imod->cindex.object && vbd->checksum != imodObjectChecksum(obj, obNum)) match = 0; if (match) return -1; } numRemnant = 0; cumQuadInd = 0; cumFanInd = 0; numVerts = 0; for (co = 0; co < obj->contsize; co++) { cont = &obj->cont[co]; setOrClearFlags(&cont->flags, ICONT_TEMPUSE, 0); if (!imodvCheckContourDraw(cont, co, checkTime)) continue; fullState = istoreContSurfDrawProps(obj->store, &defProps, &contProps, co, cont->surf, &contState, &surfState); // Skip a gap without counting it; count one to be excluded or that can't be handled if (contProps.gap) continue; skip = 0; if ((fullState & nonVboFlags) || (thickenCont && imodvCheckThickerContour(co))) skip = 1; // Check for point changes that would need to be handled if (!skip && cont->store) { if (istoreCountItems(cont->store, colorType, 1) || istoreCountItems(cont->store, GEN_STORE_TRANS, 1)) skip = 1; if (!skip && fillType <= 0 && istoreCountItems(cont->store, GEN_STORE_3DWIDTH, 1)) skip = 1; } if (skip) { setOrClearFlags(&cont->flags, ICONT_TEMPUSE, 1); numRemnant++; continue; } // Loop on the points and determine number of vertices and indices needed for each // Since we don't skip point drawing, this doesn't need store changes checked rInd.numInds = 0; rInd.numFanInds = 0; for (pt = 0; pt < cont->psize; pt++) { // Only draw zero-size points with scattered point objects drawsize = imodPointGetSize(obj, cont, pt) / xybin; if (!iobjScat(obj->flags) && !drawsize) continue; stepRes = sphereResForSize(drawsize); numVerts += sphereCounts(2 * stepRes, stepRes, fillType, rInd.numInds, rInd.numFanInds); // For a special contour, add to list of RGBT values with the counts if it // is not on the list; if it is already on the list increment its count; if (fullState & handleFlags) { rInd.firstElement = co; packRGBT(&contProps, useFillColor, contRGBT); mapret = colors.insert(pair<b3dUInt32,RGBTindices>(contRGBT, rInd)); if (mapret.second == false) { mapret.first->second.numInds += rInd.numInds; mapret.first->second.numFanInds += rInd.numFanInds; } } else { cumQuadInd += rInd.numInds; cumFanInd += rInd.numFanInds; } } } if (!numVerts) { vbCleanupSphereVBD(obj); return 2; } // Get parameters for default sphere drawsize = obj->pdrawsize / xybin; stepRes = sphereResForSize(drawsize); numDefSphVert = sphereCounts(2 * stepRes, stepRes, fillType, numDefSphQuad, numDefSphFan); imodTrace('b', "numverts %d cumfan %d cumquad %d def vert %d quad %d fan %d rem %d", numVerts, cumFanInd, cumQuadInd, numDefSphVert,numDefSphQuad, numDefSphFan, numRemnant); vbd = allocateVBDIfNeeded(&obj->vertBufSphere); if (!vbd || drawsize < 0) { vbCleanupSphereVBD(obj); return 1; } vbd->numFanIndDefault = cumFanInd; vbd->numRemnant = numRemnant; // Now allocate whatever pieces are needed in VBD // Add up the special set sizes and re-initialize the counts to be starting indexes if (allocateSpecialSets(vbd, colors.size(), cumQuadInd, 1) || processMap(vbd, &colors, cumQuadInd, 1, cumFanInd)) { vbCleanupSphereVBD(obj); return 1; } vbd->fanIndStart = cumQuadInd; // Now allocate temps plus default sphere numTriples = (1 + (fillType > 0 ? 1 : 0)) * numVerts; if (allocateTempVerts(numTriples) || allocateTempInds(cumFanInd) || allocateDefaultSphere(numDefSphVert, numDefSphQuad + numDefSphFan, fillType)) { vbCleanupSphereVBD(obj); return 1; } if (genAndBindBuffers(vbd, numTriples, cumFanInd)) { vbCleanupSphereVBD(obj); return 1; } // Build the default sphere indVert = 0; indQuad = 0; indFan = numDefSphQuad; makeSphere(drawsize, 2 * stepRes, stepRes, mDefSphVerts, mDefSphInds, indVert, indQuad, indFan, fillType, 0., 0., 0.); imodTrace('b', "numtriples %d cumquad %d cumfan %d after def vert %d quad %d fan %d", numTriples, cumQuadInd, cumFanInd, indVert, indQuad, indFan); /*for (pt = 0; pt < indFan; pt++) { imodPrintStderr(" %d", mDefSphInds[pt]); if ((pt + 1) % 16 == 0 || pt == indFan - 1) imodPrintStderr("\n"); } */ // Set the identifiers of this vb data vbd->zscale = zscale; vbd->fillType = fillType; vbd->useFillColor = useFillColor; packRGBT(&defProps, useFillColor, vbd->defaultRGBT); vbd->checkTime = checkTime; vbd->scrnScale = scrnScale; vbd->quality = quality; vbd->pdrawsize = obj->pdrawsize; vbd->thickenCont = thickenCont; vbd->checksum = imodObjectChecksum(obj, obNum); // Process contours and points in them indVert = 0; indQuadDef = 0; indFanDef = cumQuadInd; irem = 0; for (co = 0; co < obj->contsize; co++) { cont = &obj->cont[co]; if (!imodvCheckContourDraw(cont, co, checkTime)) continue; fullState = istoreContSurfDrawProps(obj->store, &defProps, &contProps, co, cont->surf, &contState, &surfState); if (contProps.gap) continue; // Add marked contours to the remnant list if (cont->flags & ICONT_TEMPUSE) { setOrClearFlags(&cont->flags, ICONT_TEMPUSE, 0); vbd->remnantIndList[irem++] = co; continue; } // Set the starting indices for the contour's quads and fans if (fullState & handleFlags) { packRGBT(&contProps, useFillColor, contRGBT); mapit = colors.find(contRGBT); indQuad = mapit->second.numInds; indFan = mapit->second.numFanInds; } else { indQuad = indQuadDef; indFan = indFanDef; } // Loop on the points and make sohere or copy the default for (pt = 0; pt < cont->psize; pt++) { drawsize = imodPointGetSize(obj, cont, pt); if (!iobjScat(obj->flags) && !drawsize) continue; if (drawsize == obj->pdrawsize) { copyDefaultSphere(mDefSphVerts, mDefSphInds, numDefSphVert, numDefSphQuad, numDefSphFan, fillType, mVerts, mInds, indVert, indQuad, indFan, cont->pts[pt].x, cont->pts[pt].y, cont->pts[pt].z * zscale); } else { drawsize /= xybin; stepRes = sphereResForSize(drawsize); makeSphere(drawsize, 2 * stepRes, stepRes, mVerts, mInds, indVert, indQuad, indFan, fillType, cont->pts[pt].x, cont->pts[pt].y, cont->pts[pt].z * zscale); } } // Save the new indices back where they came from if (fullState & handleFlags) { mapit->second.numInds = indQuad; mapit->second.numFanInds = indFan; } else { indQuadDef = indQuad; indFanDef = indFan; } } imodTrace('b', "cumfan %d after load vert %d quad %d fan %d irem %d", cumFanInd, indVert, indQuad, indFan, irem); /* for (pt = 0; pt < cumFanInd; pt++) { imodPrintStderr(" %d", mInds[pt]); if ((pt + 1) % 16 == 0 || pt == cumFanInd - 1) imodPrintStderr("\n"); } */ // Transfer to GL b3dBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, cumFanInd * sizeof(GLuint), mInds); b3dBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); b3dBufferSubData(GL_ARRAY_BUFFER, 0, numTriples * 3 * sizeof(GLfloat), mVerts); b3dBindBuffer(GL_ARRAY_BUFFER, 0); return 0; }
/* * Analyze a mesh and pack it into VBOs if it qualifies */ int VertBufManager::analyzeMesh(Imesh *mesh, float zscale, int fillType, int useFillColor, DrawProps *defProps) { bool valid = true; RGBTmap colors; pair<RGBTmap::iterator,bool> mapret; RGBTmap::iterator mapit; VertBufData *vbd = mesh->vertBuf; RGBTindices rInd; Istore *stp; Istore store; int *mlist = mesh->list; DrawProps curProps; int i, j, cumInd, defInd, nextItemIndex, stateFlags, vertDflt, changeFlags, firstDflt; b3dUInt32 vertRGBT, firstRGBT; int remInd, curSave, curNext; int numDefaultTri = 0, numMixedTri = 0; int handleFlags, nonVboFlags = 0; if (fillType) handleFlags = (useFillColor ? CHANGED_FCOLOR : CHANGED_COLOR) | CHANGED_TRANS; else { handleFlags = CHANGED_COLOR | CHANGED_TRANS; nonVboFlags = CHANGED_3DWIDTH; } rInd.numFanInds = 0; // Check if there is a current VBO and it is all still valid packRGBT(defProps, useFillColor, firstRGBT); if (vbd && vbd->vbObj && fillType == vbd->fillType && (!ilistSize(mesh->store) || (vbd->useFillColor == useFillColor && vbd->defaultRGBT == firstRGBT)) && vbd->checksum == istoreChecksum(mesh->store)) { // If Z-scale still valid, return a -1; if have to fix the Z-scale, do it, return -2 if (fabs((double)(zscale - vbd->zscale)) < 1.e-4) return -1; b3dBindBuffer(GL_ARRAY_BUFFER, vbd->vbObj); if (loadVertexNormalArray(mesh, zscale, fillType)) { vbCleanupVBD(mesh); return 1; } vbd->zscale = zscale; return -2; } // Now proceed to full analysis nextItemIndex = istoreFirstChangeIndex(mesh->store); for (i = 0; i < mesh->lsize && valid; i++) { switch (mlist[i]) { case IMOD_MESH_BGNTRI: case IMOD_MESH_ENDTRI: case IMOD_MESH_BGNPOLY: case IMOD_MESH_NORMAL: case IMOD_MESH_BGNBIGPOLY: case IMOD_MESH_SWAP: valid = false; break; case IMOD_MESH_BGNPOLYNORM: i++; while (mlist[i] != IMOD_MESH_ENDPOLY && valid) { valid = (mlist[i] == mlist[i+1] + 1) && (mlist[i+2] == mlist[i+3] + 1) && (mlist[i+4] == mlist[i+5] + 1); i += 6; numDefaultTri++; } break; case IMOD_MESH_BGNPOLYNORM2: i++; while (mlist[i] != IMOD_MESH_ENDPOLY) { if (nextItemIndex < i || nextItemIndex > i + 2) { // Count a default triangle if no changes in this range numDefaultTri++; i += 3; } else { // Otherwise look at each vertex and get its properties if it is changed for (j = 0; j < 3; j++) { vertDflt = 1; if (i == nextItemIndex) { curProps = *defProps; stateFlags = 0; nextItemIndex = istoreNextChange(mesh->store, defProps, &curProps, &stateFlags, &changeFlags); if (stateFlags & handleFlags) { vertDflt = 0; packRGBT(&curProps, useFillColor, vertRGBT); } // Take triangle as mixed if it has unhandleable flags if (stateFlags & nonVboFlags) { firstDflt = -1; i++; continue; } } // For first vertex record the triangle properties, for later one record if // there is a mismatch from the first if (!j) { firstDflt = vertDflt; firstRGBT = vertRGBT; } else if (vertDflt != firstDflt || (!vertDflt && vertRGBT != firstRGBT)) { firstDflt = -1; } i++; } // Count whether it is a default or mixed triangle if (firstDflt < 0) { numMixedTri++; } else if (firstDflt > 0) { numDefaultTri++; } else { // For a special triangle, add to list of RGBT values with a count of 1 if it // is not on the list; if it is already on the list increment its count; rInd.firstElement = i; rInd.numInds = 1; mapret = colors.insert(pair<b3dUInt32,RGBTindices>(firstRGBT, rInd)); if (mapret.second == false) mapret.first->second.numInds++; } } } break; case IMOD_MESH_END: break; } } if (!valid) { vbCleanupVBD(mesh); return 3; } if (!colors.size() && !numDefaultTri) { vbCleanupVBD(mesh); return 2; } vbd = allocateVBDIfNeeded(&mesh->vertBuf); if (!vbd) return 1; // Now allocate whatever pieces are needed in there. Set remnant value in vbd first // Add up the special set sizes and re-initialize the counts to be starting indexes cumInd = numDefaultTri * 3; vbd->numRemnant = 0; if (numMixedTri) vbd->numRemnant = numMixedTri * 3 + 3; i = -1; if (allocateSpecialSets(vbd, colors.size(), cumInd, 0) || processMap(vbd, &colors, cumInd, 3, i)) { vbCleanupVBD(mesh); return 1; } imodTrace('b',"dfltInd %d spec sets %d cumind %d remnant %d", vbd->numIndDefault, vbd->numSpecialSets, cumInd, numMixedTri); // Create the store for remnants if (numMixedTri) { ilistDelete(vbd->remnantStore); vbd->remnantStore = ilistNew(sizeof(Istore), vbd->numRemnant / 8); if (!vbd->remnantStore) { vbCleanupVBD(mesh); return 1; } vbd->remnantStore->quantum = B3DMAX(vbd->remnantStore->quantum, vbd->numRemnant / 8); vbd->remnantIndList[0] = IMOD_MESH_BGNPOLYNORM2; } // Now get the vertex buffers themselves if (genAndBindBuffers(vbd, mesh->vsize, cumInd)) { vbCleanupVBD(mesh); return 1; } imodTrace('b',"vbObj %d ebObj %d", vbd->vbObj, vbd->ebObj); // Load the vertices and finish with buffer for now if (loadVertexNormalArray(mesh, zscale, fillType)) { vbCleanupVBD(mesh); return 1; } b3dBindBuffer(GL_ARRAY_BUFFER, 0); // Set the identifiers of this vb data vbd->zscale = zscale; vbd->fillType = fillType; vbd->useFillColor = useFillColor; packRGBT(defProps, useFillColor, vbd->defaultRGBT); vbd->checksum = istoreChecksum(mesh->store); // Get or use temporary array for indexes if (allocateTempInds(cumInd)) { vbCleanupVBD(mesh); return 1; } // No fine grain: copy all the indices into index array defInd = 0; if (!mesh->store) { i = 0; while (mlist[i] != IMOD_MESH_END) { if (mlist[i] == IMOD_MESH_BGNPOLYNORM) { i++; while (mlist[i] != IMOD_MESH_ENDPOLY) { i++; mInds[defInd++] = mlist[i++] / 2; } } else if (mlist[i] == IMOD_MESH_BGNPOLYNORM2) { i++; while (mlist[i] != IMOD_MESH_ENDPOLY) { mInds[defInd++] = mlist[i++] / 2; } } i++; } } else { // Otherwise process all triangles into index array or remnant arrays nextItemIndex = istoreFirstChangeIndex(mesh->store); remInd = 1; for (i = 0; i < mesh->lsize; i++) { switch (mlist[i]) { case IMOD_MESH_BGNPOLYNORM2: i++; while (mlist[i] != IMOD_MESH_ENDPOLY) { // Repeat the analysis to determine default, special, or mixed triangle curSave = mesh->store->current; if (nextItemIndex < i || nextItemIndex > i + 2) { firstDflt = 1; } else { // Otherwise look at each vertex and get its properties if it is changed for (j = 0; j < 3; j++) { vertDflt = 1; if (i + j == nextItemIndex) { curProps = *defProps; stateFlags = 0; nextItemIndex = istoreNextChange(mesh->store, defProps, &curProps, &stateFlags, &changeFlags); if (stateFlags & handleFlags) { vertDflt = 0; packRGBT(&curProps, useFillColor, vertRGBT); } if (stateFlags & nonVboFlags) { firstDflt = -1; continue; } } // For first vertex record the triangle properties, for later one stop if // there is a mismatch from the first if (!j) { firstDflt = vertDflt; firstRGBT = vertRGBT; } else if (vertDflt != firstDflt || (!vertDflt && vertRGBT != firstRGBT)) { firstDflt = -1; } } } // Save indexes for default or special triangles if (firstDflt > 0) { mInds[defInd++] = mlist[i++] / 2; mInds[defInd++] = mlist[i++] / 2; mInds[defInd++] = mlist[i++] / 2; } else if (firstDflt == 0) { mapit = colors.find(firstRGBT); mInds[mapit->second.numInds++] = mlist[i++] / 2; mInds[mapit->second.numInds++] = mlist[i++] / 2; mInds[mapit->second.numInds++] = mlist[i++] / 2; } else { // For mixed triangle, save the current pointer, copy the index for each // vertex to the remnant index array, and copy all stores for that vertex // to the remnant store, changing the index to the new value curNext = mesh->store->current; for (j = 0; j < 3; j++) { vbd->remnantIndList[remInd] = mlist[i]; while (curSave < curNext) { stp = istoreItem(mesh->store, curSave); if (stp->index.i == i) { store = *stp; store.index.i = remInd; if (istoreInsert(&vbd->remnantStore, &store)) { vbCleanupVBD(mesh); return 1; } curSave++; } else break; } i++; remInd++; } mesh->store->current = curNext; } } break; case IMOD_MESH_END: break; } } } if (vbd->numRemnant) { vbd->remnantIndList[remInd++] = IMOD_MESH_ENDPOLY; vbd->remnantIndList[remInd++] = IMOD_MESH_END; } b3dBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, cumInd * sizeof(GLuint), mInds); b3dBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); return 0; }