void CVertexLoader::DecodeVBFormatString( const char* in_pszBuffer, CVBFormat& out_rVBFormat ) { assert(in_pszBuffer); do { std::string Token = SafeStrtok(in_pszBuffer," \t\n",in_pszBuffer); if(in_pszBuffer) { const char* pToken = Token.c_str(); if( 0==strcmp(pToken,"D3DFVF_XYZ") ) { out_rVBFormat.m_XYZ = true; } else if( 0==strcmp(pToken,"D3DFVF_NORMAL") ) { out_rVBFormat.m_Normal = true; } else if( 0==strcmp(pToken,"D3DFVF_DIFFUSE") ) { out_rVBFormat.m_Diffuse = true; } else if( 0==strcmp(pToken,"D3DFVF_TEX0") ) { out_rVBFormat.m_Tex0Dimension = CVBFormat::TEXCOORDSET_FLAT; } } } while(in_pszBuffer); }
bool CVertexLoader::Load(const std::vector<unsigned char>& in_rData ) { CBufferHolder Buffer(in_rData.size()+1); memcpy(Buffer.m_Data,&in_rData[0],in_rData.size()); Buffer.m_Data[in_rData.size()] = '\0'; std::vector<std::string> Lines; const char* pData = Buffer.m_Data; do { std::string NextLine = SafeStrtok(pData,"\r\n",pData); if(pData) { Lines.push_back( NextLine ); //CLog::Print( "%s\n", NextLine.c_str() ); } } while(pData!=NULL); if( Lines.size() < 2 ) { return false; } // get vertex format m_VBFormat.m_Diffuse = false; m_VBFormat.m_Normal = false; m_VBFormat.m_Specular = false; m_VBFormat.m_XYZ = false; m_VBFormat.m_XYZRHW = false; m_VBFormat.m_Tex0Dimension = CVBFormat::TEXCOORDSET_NONE; m_VBFormat.m_Tex1Dimension = CVBFormat::TEXCOORDSET_NONE; m_VBFormat.m_Tex2Dimension = CVBFormat::TEXCOORDSET_NONE; m_VBFormat.m_Tex3Dimension = CVBFormat::TEXCOORDSET_NONE; DecodeVBFormatString( Lines[0].c_str(), m_VBFormat ); // get primitive type DecodePrimitiveTypeString( Lines[1].c_str(), m_PrimitiveType ); // CLog::Print(" m_PrimitiveType=%lu\n",m_PrimitiveType); // get vertex data m_Data.clear(); m_IntersectData.clear(); m_NVertices = 0; unsigned int i = 2; while( i < Lines.size() ) { if( DecodeVertexString( Lines[i].c_str(), m_VBFormat, m_Data, m_IntersectData ) ) { m_NVertices++; } i++; } // CLog::Print(" m_NVertices=%lu\n",m_NVertices); m_NPrimitives = CalcNPrimitives(m_PrimitiveType,m_NVertices); return true; }
/* * Routine: * Purpose: * Algorithm: * Data Structures: * * Params: * Returns: * Called By: * Calls: * Assumptions: * Side Effects: * TODO: * 20021206 jms This routine should allow builtin integer functions like ROWCOUNT(), but they are domain specific */ int ProcessInt (char *stmt, token_t * tokens) { int nRetCode = 0; char *cp; cp = SafeStrtok(NULL, " \t,"); if (cp == NULL) return(QERR_SYNTAX); nRetCode = atoi(cp); return (nRetCode); }
/* * Routine: ProcessDistribution * Purpose: Handle creation of new dist index entry * Algorithm: * Data Structures: * * Params: * Returns: * Called By: * Calls: * Assumptions: * Side Effects: * TODO: None */ int ProcessDistribution (char *stmt, token_t * tokens) { int nRetCode = 0; char *cp; /* Validate the new substitution name and add it to the template */ cp = SafeStrtok (NULL, " \t=\r;"); if (cp == NULL) return (QERR_SYNTAX); pCurrentIndexEntry = AddDistribution (pDistIndex, cp); if (pCurrentIndexEntry == NULL) return (QERR_DEFINE_OVERFLOW); return (nRetCode); }
void CVertexLoader::DecodePrimitiveTypeString( const char* in_pszBuffer, unsigned long& out_rPrimitiveType ) { assert(in_pszBuffer); std::string Token = SafeStrtok(in_pszBuffer," \t\n",in_pszBuffer); assert(in_pszBuffer); const char* pToken = Token.c_str(); out_rPrimitiveType = 0; if( 0 == strcmp(pToken,"R8PRIM_POINT_LIST") ) out_rPrimitiveType = PRIM_POINT_LIST; else if( 0 == strcmp(pToken,"R8PRIM_LINE_LIST") ) out_rPrimitiveType = PRIM_LINE_LIST; else if( 0 == strcmp(pToken,"R8PRIM_LINE_STRIP") ) out_rPrimitiveType = PRIM_LINE_STRIP; else if( 0 == strcmp(pToken,"R8PRIM_TRIANGLE_LIST") ) out_rPrimitiveType = PRIM_TRIANGLE_LIST; else if( 0 == strcmp(pToken,"R8PRIM_TRIANGLE_STRIP") ) out_rPrimitiveType = PRIM_TRIANGLE_STRIP; else if( 0 == strcmp(pToken,"R8PRIM_TRIANGLE_FAN") ) out_rPrimitiveType = PRIM_TRIANGLE_FAN; assert(0!=out_rPrimitiveType); }
bool CVertexLoader::DecodeVertexString ( const char* in_pszBuffer ,const CVBFormat& in_rVBFormat ,std::vector<unsigned char>& out_rData ,std::vector<CVector>& out_rIntersectData ) { assert(in_pszBuffer); assert(in_rVBFormat.m_XYZ==true); if(in_pszBuffer[0]!='\0' && in_pszBuffer[0]!='#' && in_pszBuffer[0]!='\n' && in_pszBuffer[0]!='\r') { unsigned char Buffer[1024]; unsigned long NextElement = 0; // read vertex position CVector V; std::string Token = SafeStrtok(in_pszBuffer," \t\n",in_pszBuffer); assert(in_pszBuffer); V.x = (float)atof(Token.c_str()); Token = SafeStrtok(in_pszBuffer," \t\n",in_pszBuffer); assert(in_pszBuffer); V.y = (float)atof(Token.c_str()); Token = SafeStrtok(in_pszBuffer," \t\n",in_pszBuffer); assert(in_pszBuffer); V.z = (float)atof(Token.c_str()); *((CVector*)(Buffer+NextElement)) = V; NextElement += 3*sizeof(float); //CLog::Print("vertex = {%f,%f,%f}\n",V.x,V.y,V.z); assert( NextElement == sizeof(CVector) ); size_t Size = out_rIntersectData.size(); out_rIntersectData.resize( Size + 1 ); out_rIntersectData[Size] = V; if(in_rVBFormat.m_Normal) { // read normal CVector N; Token = SafeStrtok(in_pszBuffer," \t\n",in_pszBuffer); assert(in_pszBuffer); N.x =(float) atof(Token.c_str()); Token = SafeStrtok(in_pszBuffer," \t\n",in_pszBuffer); assert(in_pszBuffer); N.y = (float)atof(Token.c_str()); Token = SafeStrtok(in_pszBuffer," \t\n",in_pszBuffer); assert(in_pszBuffer); N.z = (float)atof(Token.c_str()); *((CVector*)(Buffer+NextElement)) = N; NextElement += 3*sizeof(float); //CLog::Print(" normal = {%f,%f,%f}\n",N.x,N.y,N.z); } if(in_rVBFormat.m_Diffuse) { // read diffuse color unsigned long D=0; Token = SafeStrtok(in_pszBuffer," \t\n",in_pszBuffer); assert(in_pszBuffer); int n = sscanf(Token.c_str(),"%x",&D); assert(1==n); *((unsigned long*)(Buffer+NextElement)) = D; NextElement += sizeof(unsigned long); //CLog::Print(" diffuse = %06x\n",D); } if(in_rVBFormat.m_Tex0Dimension) { assert(in_rVBFormat.m_Tex0Dimension==2); float u,v; // Token = SafeStrtok(in_pszBuffer," \t\n",in_pszBuffer); assert(in_pszBuffer); u =(float) atof(Token.c_str()); *((float*)(Buffer+NextElement)) = u; NextElement += sizeof(float); // Token = SafeStrtok(in_pszBuffer," \t\n",in_pszBuffer); assert(in_pszBuffer); v = (float)atof(Token.c_str()); *((float*)(Buffer+NextElement)) = v; NextElement += sizeof(float); // //CLog::Print(" texcoords0 = {%f,%f}\n",u,v); } Size = out_rData.size(); out_rData.resize( Size + NextElement ); unsigned char* Dst = &(out_rData[Size]); memcpy(Dst,Buffer,NextElement); return true; } else return false; }
/* * Routine: ProcessAdd * Purpose: Handle the entries themselves * Algorithm: * Data Structures: * * Params: * Returns: * Called By: * Calls: * Assumptions: * Side Effects: * TODO: None */ int ProcessAdd (char *stmt, token_t * tokens) { int i, nStrSpace = 0, nTokenLength, nExtendedLength; char *cp, *cp2, *cp3; dist_t *pCurrentDist = pCurrentIndexEntry->dist; /* confirm distribution dimensions */ if (pCurrentIndexEntry->v_width == 0) return (QERR_NO_TYPE); if (pCurrentIndexEntry->w_width == 0) return (QERR_NO_WEIGHT); /* get the values */ nStrSpace = 0; cp2 = stmt; for (i = 0; i < pCurrentIndexEntry->v_width; i++) { /* check/strip quotes from a varchar entry */ if (pCurrentDist->type_vector[i] == TKN_VARCHAR) { while (*cp2) if (*cp2 == '"') break; else cp2 += 1; if (*cp2 == '\0') ReportError (QERR_SYNTAX, "string without quotation marks", 1); cp = cp2 + 1; cp2 = cp; while (*cp2) if (*cp2 == '"') break; else cp2 += 1; if (*cp2 == '\0') ReportError (QERR_SYNTAX, "non-terminated string", 1); *cp2 = '\0'; cp2 += 1; } else { while (*cp2) if (isdigit (*cp2) || (*cp2 == '-')) break; else cp2 += 1; if (*cp2 == '\0') ReportError (QERR_SYNTAX, "invalid integer value", 1); cp = cp2; while (*cp2) if (!(isdigit (*cp2) || (*cp2 == '-'))) break; else cp2 += 1; if (*cp2 == '\0') ReportError (QERR_SYNTAX, "badly formed integer value", 1); *cp2 = '\0'; cp2 += 1; } /* remove any escaped characters from the varchar */ while ((cp3 = strchr(cp, '\\')) != NULL) memmove(cp3, cp3+1, strlen(cp3)); nTokenLength = strlen (cp); if (arValues[i] == NULL) { arValues[i] = (char *) MALLOC (sizeof (char) * (nTokenLength + 1)); if (arValues[i] == NULL) ReportError(QERR_NO_MEMORY, "arValues[]", 1); arValueLengths[i] = nTokenLength; } else if (arValueLengths[i] < nTokenLength) { arValues[i] = (char *) REALLOC (arValues[i], sizeof (char) * (nTokenLength + 1)); arValueLengths[i] = nTokenLength; } strcpy (arValues[i], cp); nStrSpace += nTokenLength + 1; } /* get the weights */ for (i = 0; i < pCurrentIndexEntry->w_width; i++) { cp = SafeStrtok (cp2, ":) \t,"); if (cp == NULL) ReportError (QERR_SYNTAX, "invalid weight count", 1); nTokenLength = strlen (cp); if (nTokenLength == 0) ReportError (QERR_SYNTAX, "zero length weight", 1); arWeights[i] = atoi (cp); cp2 = NULL; } /* if necessary, extend the distributions storage */ /* for the weights and offset values */ if (pCurrentIndexEntry->nAllocatedLength == pCurrentIndexEntry->length) { nExtendedLength = pCurrentIndexEntry->length + 100; for (i = 0; i < pCurrentIndexEntry->w_width; i++) { if (pCurrentIndexEntry->length == 0) { pCurrentDist->weight_sets[i] = (int *) MALLOC (sizeof (int) * nExtendedLength); } else { pCurrentDist->weight_sets[i] = (int *) REALLOC (pCurrentDist->weight_sets[i], sizeof (int) * nExtendedLength); } if (pCurrentDist->weight_sets[i] == NULL) return (QERR_NO_MEMORY); } for (i = 0; i < pCurrentIndexEntry->v_width; i++) { if (pCurrentIndexEntry->length == 0) { pCurrentDist->value_sets[i] = (int *) MALLOC (sizeof (int) * nExtendedLength); } else { pCurrentDist->value_sets[i] = (int *) REALLOC (pCurrentDist->value_sets[i], sizeof (int) * nExtendedLength); } if (pCurrentDist->value_sets[i] == NULL) return (QERR_NO_MEMORY); } pCurrentIndexEntry->nAllocatedLength = nExtendedLength; } /* if necessary, extend the distributions storage */ /* for the string values themselves */ if (pCurrentIndexEntry->nRemainingStrSpace <= nStrSpace) { if (pCurrentDist->strings == NULL) { pCurrentDist->strings = MALLOC (sizeof (char) * 1000); } else { pCurrentDist->strings = REALLOC (pCurrentDist->strings, pCurrentIndexEntry->str_space + sizeof (char) * 1000); } if (pCurrentDist->strings == NULL) return (QERR_NO_MEMORY); pCurrentIndexEntry->nRemainingStrSpace = 1000; } /* and now add in the new info */ for (i = 0; i < pCurrentIndexEntry->w_width; i++) *(pCurrentDist->weight_sets[i] + pCurrentIndexEntry->length) = arWeights[i]; for (i = 0; i < pCurrentIndexEntry->v_width; i++) { *(pCurrentDist->value_sets[i] + pCurrentIndexEntry->length) = pCurrentIndexEntry->str_space; cp = pCurrentDist->strings + pCurrentIndexEntry->str_space; strcpy (cp, arValues[i]); pCurrentIndexEntry->str_space += strlen (arValues[i]) + 1; } pCurrentIndexEntry->length += 1; pCurrentIndexEntry->nRemainingStrSpace -= nStrSpace; return (0); }
/* * Routine: ProcessSet * Purpose: Read distribution settings * Algorithm: * Data Structures: * * Params: * Returns: * Called By: * Calls: * Assumptions: * Side Effects: * TODO: None * * NOTE: if QERR_SYNTAX can be a valid return value, we have a problem. */ int ProcessSet (char *stmt, token_t * tokens) { int nRetCode = 0, i; char *cp = NULL; cp = SafeStrtok (NULL, " \t="); switch (i = FindToken (cp)) { case TKN_WEIGHTS: cp = SafeStrtok (NULL, " \t"); /* discard = */ pCurrentIndexEntry->w_width = ProcessInt (stmt, tokens); if (pCurrentIndexEntry->w_width == QERR_SYNTAX) nRetCode = QERR_RANGE_ERROR; else { if (pCurrentIndexEntry->w_width > nMaxWeightWidth) { arWeights = (int *) REALLOC (arWeights, pCurrentIndexEntry->w_width * sizeof (int)); if (arWeights == NULL) nRetCode = QERR_NO_MEMORY; } else nMaxWeightWidth = pCurrentIndexEntry->w_width; } pCurrentIndexEntry->dist->weight_sets = (int **) MALLOC (pCurrentIndexEntry->w_width * sizeof (int *)); if (pCurrentIndexEntry->dist->weight_sets == NULL) nRetCode = QERR_NO_MEMORY; memset(pCurrentIndexEntry->dist->weight_sets, 0, pCurrentIndexEntry->w_width * sizeof(int *)); break; case TKN_TYPES: pCurrentIndexEntry->v_width = ProcessTypes (stmt, tokens); if (pCurrentIndexEntry->v_width == QERR_SYNTAX) nRetCode = QERR_RANGE_ERROR; else { if (pCurrentIndexEntry->v_width > nMaxValueWidth) { arValues = (char **) REALLOC (arValues, pCurrentIndexEntry->v_width * sizeof (char *)); arValueLengths = (int *) REALLOC (arValueLengths, pCurrentIndexEntry->v_width * sizeof (int)); } if (arValues == NULL || arValueLengths == NULL) nRetCode = QERR_NO_MEMORY; else { for (i=nMaxValueWidth; i < pCurrentIndexEntry->v_width; i++) { arValueLengths[i] = 0; arValues[i] = NULL; } nMaxValueWidth = pCurrentIndexEntry->v_width; } } pCurrentIndexEntry->dist->value_sets = (int **) MALLOC (pCurrentIndexEntry->v_width * sizeof (int *)); if (pCurrentIndexEntry->dist->value_sets == NULL) nRetCode = QERR_NO_MEMORY; memset(pCurrentIndexEntry->dist->value_sets, 0, pCurrentIndexEntry->v_width * sizeof(int *)); break; case TKN_NAMES: if ((pCurrentIndexEntry->v_width <= 0) || (pCurrentIndexEntry->w_width <= 0)) return(QERR_NAMES_EARLY); pCurrentIndexEntry->name_space = ProcessNames(stmt, tokens); break; default: nRetCode = QERR_SYNTAX; } return (nRetCode); }