RetType put<const float3& >(VM vm, const float3 & f) { putFloat(vm,f[0]); putFloat(vm,f[1]); putFloat(vm,f[2]); return 3; }
RetType put<float3>(VM vm, float3 f) { putFloat(vm,f[0]); putFloat(vm,f[1]); putFloat(vm,f[2]); return 3; }
void da_setupScale() { high(pinCh0); high(pinCh1); pause(5); float vA = ad_volts(0); float vB = ad_volts(1); //print("%f %f\n", vA, vB); if( (vA > 3.1 && vA < 3.5 && vB > 3.1 && vB < 3.5)) { for(int i = 0; i < 39; i++) { vA += ad_volts(0); vB += ad_volts(1); } vA /= 40; vB /= 40; vA = 3.3 / vA; vB = 3.3 / vB; int addr = _abvolts_EE_start_; ee_putStr("abvolts", 8, addr); addr += 8; ee_putFloat32(vA, addr); addr += 4; ee_putFloat32(vB, addr); addr += 4; low(pinCh0); low(pinCh1); input(pinCh0); input(pinCh1); putStr("Ch0 scalar = "); putFloat(vA); putStr("\nCh1 scalar = "); putFloat(vB); putChar('\n'); putChar('\n'); abvolts_scale[0] = vA; abvolts_scale[1] = vB; } else { putStr("Error! Something went wrong. Check your circuit and power source."); } }
uint64_t serialise(std::ostream & out) const { uint64_t offset = 0; putLittleEndianInteger4(out,ureads,offset); putLittleEndianInteger4(out,treads,offset); putLittleEndianInteger4(out,cutoff,offset); putLittleEndianInteger4(out,all,offset); for ( size_t i = 0; i < sizeof(freq)/sizeof(freq[0]); ++i ) putFloat(out,freq[i],offset); putLittleEndianInteger4(out,maxlen,offset); putLittleEndianInteger8(out,totlen,offset); putLittleEndianInteger4(out,nreads,offset); putLittleEndianInteger4(out,trimmed,offset); putLittleEndianInteger4(out,0,offset); // part putLittleEndianInteger4(out,0,offset); // ufirst putLittleEndianInteger4(out,0,offset); // tfirst putLittleEndianInteger8(out,0,offset); // path putLittleEndianInteger4(out,0,offset); // loaded putLittleEndianInteger8(out,0,offset); // bases putLittleEndianInteger8(out,0,offset); // reads putLittleEndianInteger8(out,0,offset); // tracks return offset; }
////////////////////////////////////////////////////////////////////////// // Vector2 bool BasePersistenceManager::transferVector2(const char *name, Vector2 *val) { if (_saving) { putFloat(val->x); putFloat(val->y); if (_saveStream->err()) { return STATUS_FAILED; } return STATUS_OK; } else { val->x = getFloat(); val->y = getFloat(); if (_loadStream->err()) { return STATUS_FAILED; } return STATUS_OK; } }
encode() { Packet::encode(); buffer+=ID; putInt(seed); putByte(dimension); putInt(generator); putInt(gamemode); putLong(eid); putInt(spawnX); putInt(spawnY); putInt(spawnZ); putFloat(x); putFloat(y); putFloat(z); putByte('\0'); }
int dumpNBT_list(NBT_list *input, uint8 *buffer) { int curpos=0; buffer[curpos]=TAG_LIST; curpos++; curpos+=dumpNBT_string(&buffer[curpos],input->name); buffer[curpos]=input->tagId; curpos++; putSint32(&buffer[curpos],input->length); curpos+=4; for(int i=0; i<input->length; i++) { switch(input->tagId) { case TAG_BYTE: buffer[curpos]=*(char *)input->items[i]; curpos++; break; case TAG_SHORT: putSint16(&buffer[curpos], *(int *)input->items[i]); curpos+=2; break; case TAG_INT: putSint32(&buffer[curpos], *(int *)input->items[i]); curpos+=4; break; case TAG_LONG: putSint64(&buffer[curpos], *(long long *)input->items[i]); curpos+=8; break; case TAG_FLOAT: putFloat(&buffer[curpos], *(float *)input->items[i]); curpos+=4; break; case TAG_DOUBLE: putDouble(&buffer[curpos], *(double *)input->items[i]); curpos+=8; break; case TAG_STRING: curpos+=dumpNBT_string(&buffer[curpos],*(std::string *)input->items[i]); break; case TAG_BYTE_ARRAY: curpos+=dumpNBT_byte_array((NBT_byte_array *)input->items[i], &buffer[curpos],true); break; case TAG_COMPOUND: curpos+=dumpNBT_struct((NBT_struct *)input->items[i], &buffer[curpos],true); break; } } return curpos; }
/* * Class: sun_font_SunLayoutEngine * Method: nativeLayout * Signature: (Lsun/font/FontStrike;[CIIIIZLjava/awt/geom/Point2D$Float;Lsun/font/GlyphLayout$GVData;)V */ JNIEXPORT void JNICALL Java_sun_font_SunLayoutEngine_nativeLayout (JNIEnv *env, jclass cls, jobject font2d, jobject strike, jfloatArray matrix, jint gmask, jint baseIndex, jcharArray text, jint start, jint limit, jint min, jint max, jint script, jint lang, jint typo_flags, jobject pt, jobject gvdata, jlong upem, jlong layoutTables) { // fprintf(stderr, "nl font: %x strike: %x script: %d\n", font2d, strike, script); fflush(stderr); float mat[4]; env->GetFloatArrayRegion(matrix, 0, 4, mat); FontInstanceAdapter fia(env, font2d, strike, mat, 72, 72, (le_int32) upem, (TTLayoutTableCache *) layoutTables); LEErrorCode success = LE_NO_ERROR; LayoutEngine *engine = LayoutEngine::layoutEngineFactory(&fia, script, lang, typo_flags & TYPO_MASK, success); if (min < 0) min = 0; if (max < min) max = min; /* defensive coding */ // have to copy, yuck, since code does upcalls now. this will be soooo slow jint len = max - min; jchar buffer[256]; jchar* chars = buffer; if (len > 256) { size_t size = len * sizeof(jchar); if (size / sizeof(jchar) != len) { return; } chars = (jchar*)malloc(size); if (chars == 0) { return; } } // fprintf(stderr, "nl chars: %x text: %x min %d len %d typo %x\n", chars, text, min, len, typo_flags); fflush(stderr); env->GetCharArrayRegion(text, min, len, chars); jfloat x, y; getFloat(env, pt, x, y); jboolean rtl = (typo_flags & TYPO_RTL) != 0; int glyphCount = engine->layoutChars(chars, start - min, limit - start, len, rtl, x, y, success); // fprintf(stderr, "sle nl len %d -> gc: %d\n", len, glyphCount); fflush(stderr); engine->getGlyphPosition(glyphCount, x, y, success); // fprintf(stderr, "layout glyphs: %d x: %g y: %g\n", glyphCount, x, y); fflush(stderr); if (putGV(env, gmask, baseIndex, gvdata, engine, glyphCount)) { // !!! hmmm, could use current value in positions array of GVData... putFloat(env, pt, x, y); } if (chars != buffer) { free(chars); } delete engine; }
////////////////////////////////////////////////////////////////////////// // float bool BasePersistenceManager::transferFloat(const char *name, float *val) { if (_saving) { putFloat(*val); if (_saveStream->err()) { return STATUS_FAILED; } return STATUS_OK; } else { *val = getFloat(); if (_loadStream->err()) { return STATUS_FAILED; } return STATUS_OK; } }
int dumpNBT_value(NBT_value *input, uint8 *buffer) { int curpos=0; buffer[curpos]=input->type; curpos++; curpos+=dumpNBT_string(&buffer[curpos],input->name); switch(input->type) { case TAG_BYTE: buffer[curpos]=*(char *)input->value; curpos++; break; case TAG_SHORT: putSint16(&buffer[curpos], *(int *)input->value); curpos+=2; break; case TAG_INT: putSint32(&buffer[curpos], *(int *)input->value); curpos+=4; break; case TAG_LONG: putSint64(&buffer[curpos], *(long long *)input->value); curpos+=8; break; case TAG_FLOAT: putFloat(&buffer[curpos], *(float *)input->value); curpos+=4; break; case TAG_DOUBLE: putDouble(&buffer[curpos], *(double *)input->value); curpos+=8; break; case TAG_STRING: curpos+=dumpNBT_string(&buffer[curpos],*(std::string *)input->value); break; } return curpos; }
void NBT_Value::Write(std::vector<uint8> &buffer) { int storeAt = buffer.size();; switch(m_type) { case TAG_BYTE: buffer.push_back(m_value.byteVal); break; case TAG_SHORT: buffer.resize(storeAt + 2); putSint16(&buffer[storeAt], m_value.shortVal); break; case TAG_INT: buffer.resize(storeAt + 4); putSint32(&buffer[storeAt], m_value.intVal); break; case TAG_LONG: buffer.resize(storeAt + 8); putSint64(&buffer[storeAt], m_value.longVal); break; case TAG_FLOAT: buffer.resize(storeAt + 4); putFloat(&buffer[storeAt], m_value.floatVal); break; case TAG_DOUBLE: buffer.resize(storeAt + 8); putDouble(&buffer[storeAt], m_value.doubleVal); break; case TAG_BYTE_ARRAY: { int arraySize = m_value.byteArrayVal ? m_value.byteArrayVal->size() : 0; buffer.resize(storeAt + 4 + arraySize); putSint32(&buffer[storeAt], arraySize); storeAt += 4; if(arraySize) memcpy(&buffer[storeAt], &(*m_value.byteArrayVal)[0], arraySize); break; } case TAG_STRING: { int stringLen = m_value.stringVal ? m_value.stringVal->size() : 0; buffer.resize(storeAt + 2 + stringLen); putSint16(&buffer[storeAt], (sint16)stringLen); storeAt += 2; if(stringLen>0) memcpy(&buffer[storeAt], m_value.stringVal->c_str(), stringLen); break; } case TAG_LIST: { buffer.resize(storeAt + 5); int listCount = m_value.listVal.data ? m_value.listVal.data->size() : 0; buffer[storeAt] = m_value.listVal.type; storeAt++; putSint32(&buffer[storeAt], listCount); for(int i=0;i<listCount;i++) (*m_value.listVal.data)[i]->Write(buffer); break; } case TAG_COMPOUND: { int compoundCount = m_value.compoundVal ? m_value.compoundVal->size() : 0; if(compoundCount) { std::map<std::string, NBT_Value*>::iterator iter = m_value.compoundVal->begin(), end = m_value.compoundVal->end(); for( ; iter != end; iter++) { const std::string &key = iter->first; int keySize = key.size(); NBT_Value *val = iter->second; int curPos = buffer.size(); buffer.resize(curPos + 3 + keySize); buffer[curPos] = (uint8)val->GetType(); curPos++; putSint16(&buffer[curPos], keySize); curPos += 2; if(keySize) memcpy(&buffer[curPos], key.c_str(), keySize); val->Write(buffer); } } buffer.push_back(TAG_END); break; } case TAG_END: break; //for completeness } }
int ExportQuake3Model(const TCHAR *filename, ExpInterface *ei, Interface *gi, int start_time, std::list<ExportNode> lTags, std::list<ExportNode> lMeshes) { FILE *file; int i, j, totalTags, totalMeshes, current_time = 0; long pos_current, totalTris = 0, totalVerts = 0; std::list<FrameRange>::iterator range_i; std::vector<Point3> lFrameBBoxMin; std::vector<Point3> lFrameBBoxMax; long pos_tagstart; long pos_tagend; long pos_filesize; long pos_framestart; int lazynamesfixed = 0; const Point3 x_axis(1, 0, 0); const Point3 z_axis(0, 0, 1); SceneEnumProc checkScene(ei->theScene, start_time, gi); totalTags = (int)lTags.size(); if (g_tag_for_pivot) totalTags++; totalMeshes = (int)lMeshes.size(); // open file file = _tfopen(filename, _T("wb")); if (!file) { ExportError("Cannot open file '%s'.", filename); return FALSE; } ExportDebug("%s:", filename); // sync pattern and version putChars("IDP3", 4, file); put32(15, file); putChars("Darkplaces MD3 Exporter", 64, file); put32(0, file); // flags // MD3 header ExportState("Writing MD3 header"); put32(g_total_frames, file); // how many frames put32(totalTags, file); // tagsnum put32(totalMeshes, file); // meshnum put32(1, file); // maxskinnum put32(108, file); // headersize pos_tagstart = ftell(file); put32(0, file); // tagstart pos_tagend = ftell(file); put32(256, file); // tagend pos_filesize = ftell(file); put32(512, file); // filesize ExportDebug(" %i frames, %i tags, %i meshes", g_total_frames, totalTags, totalMeshes); // frame info // bbox arrays get filled while exported mesh and written back then ExportState("Writing frame info"); pos_framestart = ftell(file); lFrameBBoxMin.resize(g_total_frames); lFrameBBoxMax.resize(g_total_frames); for (i = 0; i < g_total_frames; i++) { // init frame data lFrameBBoxMin[i].Set(0, 0, 0); lFrameBBoxMax[i].Set(0, 0, 0); // put data putFloat(-1.0f, file); // bbox min vector putFloat(-1.0f, file); putFloat(-1.0f, file); putFloat( 1.0f, file); // bbox max vector putFloat(1.0f, file); putFloat(1.0f, file); putFloat(0.0f, file); // local origin (usually 0 0 0) putFloat(0.0f, file); putFloat(0.0f, file); putFloat(1.0f, file); // radius of bounding sphere putChars("", 16, file); } // tags pos_current = ftell(file); fseek(file, pos_tagstart, SEEK_SET); put32(pos_current, file); fseek(file, pos_current, SEEK_SET); // for each frame range cycle all frames and write out each tag long pos_tags = pos_current; if (totalTags) { long current_frame = 0; ExportState("Writing %i tags", totalTags); for (range_i = g_frame_ranges.begin(); range_i != g_frame_ranges.end(); range_i++) { for (i = (*range_i).first; i <= (int)(*range_i).last; i++, current_frame++) { SceneEnumProc current_scene(ei->theScene, i * g_ticks_per_frame, gi); current_time = current_scene.time; // write out tags if (lTags.size()) { for (std::list<ExportNode>::iterator tag_i = lTags.begin(); tag_i != lTags.end(); tag_i++) { INode *node = current_scene[tag_i->i]->node; Matrix3 tm = node->GetObjTMAfterWSM(current_time); ExportState("Writing '%s' frame %i of %i", tag_i->name, i, g_total_frames); // tagname putChars(tag_i->name, 64, file); // origin, rotation matrix Point3 row = tm.GetRow(3); putFloat(row.x, file); putFloat(row.y, file); putFloat(row.z, file); row = tm.GetRow(0); putFloat(row.x, file); putFloat(row.y, file); putFloat(row.z, file); row = tm.GetRow(1); putFloat(row.x, file); putFloat(row.y, file); putFloat(row.z, file); row = tm.GetRow(2); putFloat(row.x, file); putFloat(row.y, file); putFloat(row.z, file); } } // write the center of mass tag_pivot which is avg of all objects's pivots if (g_tag_for_pivot) { ExportState("Writing 'tag_pivot' frame %i of %i", i, g_total_frames); // write the null data as tag_pivot need to be written after actual geometry // (it needs information on frame bound boxes to get proper blendings) putChars("tag_pivot", 64, file); putFloat(0, file); putFloat(0, file); putFloat(0, file); putFloat(1, file); putFloat(0, file); putFloat(0, file); putFloat(0, file); putFloat(1, file); putFloat(0, file); putFloat(0, file); putFloat(0, file); putFloat(1, file); } } } } // write the tag object offsets pos_current = ftell(file); fseek(file, pos_tagend, SEEK_SET); put32(pos_current, file); fseek(file, pos_current, SEEK_SET); // allocate the structs used to calculate tag_pivot std::vector<Point3> tag_pivot_origin; std::vector<double> tag_pivot_volume; if (g_tag_for_pivot) { tag_pivot_origin.resize(g_total_frames); tag_pivot_volume.resize(g_total_frames); } // mesh objects // for each mesh object write uv and frames SceneEnumProc scratch(ei->theScene, start_time, gi); ExportState("Writing %i meshes", (int)lMeshes.size()); for (std::list<ExportNode>::iterator mesh_i = lMeshes.begin(); mesh_i != lMeshes.end(); mesh_i++) { bool needsDel; ExportState("Start mesh #%i", mesh_i); INode *node = checkScene[mesh_i->i]->node; Matrix3 tm = node->GetObjTMAfterWSM(start_time); TriObject *tri = GetTriObjectFromNode(node, start_time, needsDel); if (!tri) continue; // get mesh, compute normals Mesh &mesh = tri->GetMesh(); MeshNormalSpec *meshNormalSpec = mesh.GetSpecifiedNormals(); if (meshNormalSpec) { if (!meshNormalSpec->GetNumFaces()) meshNormalSpec = NULL; else { meshNormalSpec->SetParent(&mesh); meshNormalSpec->CheckNormals(); } } mesh.checkNormals(TRUE); // fix lazy object names ExportState("Attempt to fix mesh name '%s'", mesh_i->name); char meshname[64]; size_t meshnamelen = min(63, strlen(mesh_i->name)); memset(meshname, 0, 64); strncpy(meshname, mesh_i->name, meshnamelen); meshname[meshnamelen] = 0; if (!strncmp("Box", meshname, 3) || !strncmp("Sphere", meshname, 6) || !strncmp("Cylinder", meshname, 8) || !strncmp("Torus", meshname, 5) || !strncmp("Cone", meshname, 4) || !strncmp("GeoSphere", meshname, 9) || !strncmp("Tube", meshname, 4) || !strncmp("Pyramid", meshname, 7) || !strncmp("Plane", meshname, 5) || !strncmp("Teapot", meshname, 6) || !strncmp("Object", meshname, 6)) { name_conflict: lazynamesfixed++; if (lazynamesfixed == 1) strcpy(meshname, "base"); else sprintf(meshname, "base%i", lazynamesfixed); // check if it's not used by another mesh for (std::list<ExportNode>::iterator m_i = lMeshes.begin(); m_i != lMeshes.end(); m_i++) if (!strncmp(m_i->name, meshname, strlen(meshname))) goto name_conflict; // approve name ExportWarning("Lazy object name '%s' (mesh renamed to '%s').", node->GetName(), meshname); } // special mesh check bool shadow_or_collision = false; if (g_mesh_special) if (!strncmp("collision", meshname, 9) || !strncmp("shadow", meshname, 6)) shadow_or_collision = true; // get material const char *shadername = NULL; Texmap *tex = 0; Mtl *mtl = 0; if (!shadow_or_collision) { mtl = node->GetMtl(); if (mtl) { // check for multi-material if (mtl->IsMultiMtl()) { // check if it's truly multi material // we do support multi-material with only one texture (some importers set it) bool multi_material = false; MtlID matId = mesh.faces[0].getMatID(); for (i = 1; i < mesh.getNumFaces(); i++) if (mesh.faces[i].getMatID() != matId) multi_material = true; if (multi_material) if (g_mesh_multimaterials == MULTIMATERIALS_NONE) ExportWarning("Object '%s' is multimaterial and using multiple materials on its faces, that case is not yet supported (truncating to first submaterial).", node->GetName()); // switch to submaterial mtl = mtl->GetSubMtl(matId); } // get shader from material if supplied char *materialname = GetChar(mtl->GetName()); if (g_mesh_materialasshader && (strstr(materialname, "/") != NULL || strstr(materialname, "\\") != NULL)) shadername = GetChar(mtl->GetName()); else { // get texture tex = mtl->GetSubTexmap(ID_DI); if (tex) { if (tex->ClassID() == Class_ID(BMTEX_CLASS_ID, 0x00)) { shadername = GetChar(((BitmapTex *)tex)->GetMapName()); if (shadername == NULL || !shadername[0]) ExportWarning("Object '%s' material '%s' has no bitmap.", tex->GetName(), node->GetName()); } else { tex = NULL; ExportWarning("Object '%s' has material with wrong texture type (only Bitmap are supported).", node->GetName()); } } else ExportWarning("Object '%s' has material but no texture.", node->GetName()); } } else ExportWarning("Object '%s' has no material.", node->GetName()); } long pos_meshstart = ftell(file); // surface object ExportState("Writing mesh '%s' header", meshname); putChars("IDP3", 4, file); putChars(meshname, 64, file); put32(0, file); // flags put32(g_total_frames, file); // framecount put32(1, file); // skincount long pos_vertexnum = ftell(file); put32(0, file); // vertexcount put32(mesh.getNumFaces(), file); // trianglecount long pos_trianglestart = ftell(file); put32(0, file); // start triangles put32(108, file); // header size long pos_texvecstart = ftell(file); put32(0, file); // texvecstart long pos_vertexstart = ftell(file); put32(16, file); // vertexstart long pos_meshsize = ftell(file); put32(32, file); // meshsize // write out a single 'skin' ExportState("Writing mesh %s texture", meshname); if (shadow_or_collision) putChars(meshname, 64, file); else if (shadername) putMaterial(shadername, mtl, tex, file); else putChars("noshader", 64, file); put32(0, file); // flags // build geometry ExportState("Building vertexes/triangles"); std::vector<ExportVertex>vVertexes; std::vector<ExportTriangle>vTriangles; vVertexes.resize(mesh.getNumVerts()); int vExtraVerts = mesh.getNumVerts(); for (i = 0; i < mesh.getNumVerts(); i++) { vVertexes[i].vert = i; vVertexes[i].normalfilled = false; // todo: check for coincident verts } int vNumExtraVerts = 0; // check normals if (!mesh.normalsBuilt && !shadow_or_collision) ExportWarning("Object '%s' does not have normals contructed.", node->GetName()); // get info for triangles const float normal_epsilon = 0.01f; vTriangles.resize(mesh.getNumFaces()); for (i = 0; i < mesh.getNumFaces(); i++) { DWORD smGroup = mesh.faces[i].getSmGroup(); ExportState("Mesh %s: checking normals for face %i of %i", meshname, i, mesh.getNumFaces()); for (j = 0; j < 3; j++) { int vert = mesh.faces[i].getVert(j); vTriangles[i].e[j] = vert; // find a right normal for this vertex and save its 'address' int vni; Point3 vn; if (!mesh.normalsBuilt || shadow_or_collision) { vn.Set(0, 0, 0); vni = 0; } else { int numNormals; RVertex *rv = mesh.getRVertPtr(vert); if (meshNormalSpec) { ExportState("face %i vert %i have normal specified", i, j); // mesh have explicit normals (i.e. Edit Normals modifier) vn = meshNormalSpec->GetNormal(i, j); vni = meshNormalSpec->GetNormalIndex(i, j); } else if (rv && rv->rFlags & SPECIFIED_NORMAL) { ExportState("face %i vert %i have SPECIFIED_NORMAL flag", i, j); // SPECIFIED_NORMAL flag vn = rv->rn.getNormal(); vni = 0; } else if (rv && (numNormals = rv->rFlags & NORCT_MASK) && smGroup) { // If there is only one vertex is found in the rn member. if (numNormals == 1) { ExportState("face %i vert %i have solid smooth group", i, j); vn = rv->rn.getNormal(); vni = 0; } else { ExportState("face %i vert %i have mixed smoothing groups", i, j); // If two or more vertices are there you need to step through them // and find the vertex with the same smoothing group as the current face. // You will find multiple normals in the ern member. for (int k = 0; k < numNormals; k++) { if (rv->ern[k].getSmGroup() & smGroup) { vn = rv->ern[k].getNormal(); vni = 1 + k; } } } } else { ExportState("face %i vert %i flat shaded", i, j); // Get the normal from the Face if no smoothing groups are there vn = mesh.getFaceNormal(i); vni = 0 - (i + 1); } } // subdivide to get all normals right if (!vVertexes[vert].normalfilled) { vVertexes[vert].normal = vn; vVertexes[vert].normalindex = vni; vVertexes[vert].normalfilled = true; } else if ((vVertexes[vert].normal - vn).Length() >= normal_epsilon) { // current vertex not matching normal - it was already filled by different smoothing group // find a vert in extra verts in case it was already created bool vert_found = false; for (int ev = vExtraVerts; ev < (int)vVertexes.size(); ev++) { if (vVertexes[ev].vert == vert && (vVertexes[ev].normal - vn).Length() < normal_epsilon) { vert_found = true; vTriangles[i].e[j] = ev; break; } } // we havent found a vertex, create new if (!vert_found) { ExportVertex NewVert; NewVert.vert = vVertexes[vert].vert; NewVert.normal = vn; NewVert.normalindex = vni; NewVert.normalfilled = true; vTriangles[i].e[j] = (int)vVertexes.size(); vVertexes.push_back(NewVert); vNumExtraVerts++; } } } } int vNumExtraVertsForSmoothGroups = vNumExtraVerts; // generate UV map // VorteX: use direct maps reading since getNumTVerts()/getTVert is deprecated // max sets two default mesh maps: 0 - vertex color, 1 : UVW, 2 & up are custom ones ExportState("Building UV map"); std::vector<ExportUV>vUVMap; vUVMap.resize(vVertexes.size()); int meshMap = 1; if (!mesh.mapSupport(meshMap) || !mesh.getNumMapVerts(meshMap) || shadow_or_collision) { for (i = 0; i < mesh.getNumVerts(); i++) { vUVMap[i].u = 0.5; vUVMap[i].v = 0.5; } if (!shadow_or_collision) ExportWarning("No UV mapping was found on object '%s'.", node->GetName()); } else { UVVert *meshUV = mesh.mapVerts(meshMap); for (i = 0; i < (int)vTriangles.size(); i++) { ExportState("Mesh %s: converting tvert for face %i of %i", meshname, i, (int)vTriangles.size()); // for 3 face vertexes for (j = 0; j < 3; j++) { int vert = vTriangles[i].e[j]; int tv = mesh.tvFace[i].t[j]; UVVert &UV = meshUV[tv]; if (!vUVMap[vert].filled) { // fill uvMap vertex vUVMap[vert].u = UV.x; vUVMap[vert].v = UV.y; vUVMap[vert].filled = true; vUVMap[vert].tvert = tv; } else if (tv != vUVMap[vert].tvert) { // uvMap slot for this vertex has been filled // we should arrange triangle to other vertex, which not filled and having same shading and uv // check if any of the extra vertices can fit bool vert_found = false; for (int ev = vExtraVerts; ev < (int)vVertexes.size(); ev++) { if (vVertexes[ev].vert == vert && vUVMap[vert].u == UV.x &&vUVMap[vert].v == UV.y && (vVertexes[ev].normal - vVertexes[vert].normal).Length() < normal_epsilon) { vert_found = true; vTriangles[i].e[j] = vVertexes[ev].vert; break; } } if (!vert_found) { // create new vert ExportVertex NewVert; NewVert.vert = vVertexes[vert].vert; NewVert.normal = vVertexes[vert].normal; NewVert.normalindex = vVertexes[vert].normalindex; NewVert.normalfilled = vVertexes[vert].normalfilled; vTriangles[i].e[j] = (int)vVertexes.size(); vVertexes.push_back(NewVert); vNumExtraVerts++; // create new TVert ExportUV newUV; newUV.filled = true; newUV.u = UV.x; newUV.v = UV.y; newUV.tvert = tv; vUVMap.push_back(newUV); } } } } } int vNumExtraVertsForUV = (vNumExtraVerts - vNumExtraVertsForSmoothGroups); // print some debug stats ExportDebug(" mesh %s: %i vertexes +%i %s +%i UV, %i triangles", meshname, ((int)vVertexes.size() - vNumExtraVerts), vNumExtraVertsForSmoothGroups, meshNormalSpec ? "EditNormals" : "SmoothGroups", vNumExtraVertsForUV, (int)vTriangles.size()); // fill in triangle start pos_current = ftell(file); fseek(file, pos_trianglestart, SEEK_SET); put32(pos_current - pos_meshstart, file); fseek(file, pos_current, SEEK_SET); // detect if object have negative scale (mirrored) // in this canse we should rearrange triangles counterclockwise // so stuff will not be inverted ExportState("Mesh %s: writing %i triangles", meshname, (int)vTriangles.size()); if (DotProd(CrossProd(tm.GetRow(0), tm.GetRow(1)), tm.GetRow(2)) < 0.0) { ExportWarning("Object '%s' is mirrored (having negative scale on it's transformation)", node->GetName()); for (i = 0; i < (int)vTriangles.size(); i++) { put32(vTriangles[i].b, file); // vertex index put32(vTriangles[i].c, file); // for 3 vertices put32(vTriangles[i].a, file); // of triangle } } else { for (i = 0; i < (int)vTriangles.size(); i++) { put32(vTriangles[i].a, file); // vertex index put32(vTriangles[i].c, file); // for 3 vertices put32(vTriangles[i].b, file); // of triangle } } // fill in texvecstart // write out UV mapping coords. ExportState("Mesh %s: writing %i UV vertexes", meshname, (int)vUVMap.size()); pos_current = ftell(file); fseek(file, pos_texvecstart, SEEK_SET); put32(pos_current - pos_meshstart, file); fseek(file, pos_current, SEEK_SET); for (i = 0; i < (int)vUVMap.size(); i++) { putFloat(vUVMap[i].u, file); // texture coord u,v putFloat(1.0f - vUVMap[i].v, file); // for vertex } vUVMap.clear(); // fill in vertexstart pos_current = ftell(file); fseek(file, pos_vertexstart, SEEK_SET); put32(pos_current - pos_meshstart, file); fseek(file, pos_current, SEEK_SET); // fill in vertexnum pos_current = ftell(file); fseek(file, pos_vertexnum, SEEK_SET); put32((int)vVertexes.size(), file); fseek(file, pos_current, SEEK_SET); // write out for each frame the position of each vertex long current_frame = 0; ExportState("Mesh %s: writing %i frames", meshname, g_total_frames); for (range_i = g_frame_ranges.begin(); range_i != g_frame_ranges.end(); range_i++) { for (i = (*range_i).first; i <= (int)(*range_i).last; i++, current_frame++) { bool _needsDel; // get triobject for current frame SceneEnumProc current_scene(ei->theScene, i * g_ticks_per_frame, gi); current_time = current_scene.time; INode *_node = current_scene[mesh_i->i]->node; TriObject *_tri = GetTriObjectFromNode(_node, current_time, _needsDel); if (!_tri) continue; // get mesh, compute normals Mesh &_mesh = _tri->GetMesh(); MeshNormalSpec *_meshNormalSpec = _mesh.GetSpecifiedNormals(); if (_meshNormalSpec) { if (!_meshNormalSpec->GetNumFaces()) _meshNormalSpec = NULL; else { _meshNormalSpec->SetParent(&_mesh); _meshNormalSpec->CheckNormals(); } } _mesh.checkNormals(TRUE); // get transformations for current frame Matrix3 _tm = _node->GetObjTMAfterWSM(current_time); ExportState("Mesh %s: writing frame %i of %i", meshname, current_frame, g_total_frames); Point3 BoxMin(0, 0, 0); Point3 BoxMax(0, 0, 0); for (j = 0; j < (int)vVertexes.size(); j++) // number of vertices { ExportState("Mesh %s: transform vertex %i of %i", meshname, j, (int)vVertexes.size()); int vert = vVertexes[j].vert; Point3 &v = _tm.PointTransform(_mesh.getVert(vert)); // populate bbox data if (!shadow_or_collision) { BoxMin.x = min(BoxMin.x, v.x); BoxMin.y = min(BoxMin.y, v.y); BoxMin.z = min(BoxMin.z, v.z); BoxMax.x = max(BoxMax.x, v.x); BoxMax.y = max(BoxMax.y, v.y); BoxMax.z = max(BoxMax.z, v.z); } // write vertex double f; f = v.x * 64.0f; if (f < -32768.0) f = -32768.0; if (f > 32767.0) f = 32767.0; put16((short)f, file); f = v.y * 64.0f; if (f < -32768.0) f = -32768.0; if (f > 32767.0) f = 32767.0; put16((short)f, file); f = v.z * 64.0f; if (f < -32768.0) f = -32768.0; if (f > 32767.0) f = 32767.0; put16((short)f, file); // get normal ExportState("Mesh %s: transform vertex normal %i of %i", meshname, j, (int)vVertexes.size()); Point3 n; if (_meshNormalSpec) // mesh have explicit normals (i.e. Edit Normals modifier) n = _meshNormalSpec->Normal(vVertexes[j].normalindex); else if (!vVertexes[j].normalfilled || !_mesh.normalsBuilt) n = _mesh.getNormal(vert); else { RVertex *rv = _mesh.getRVertPtr(vert); if (vVertexes[j].normalindex < 0) n = _mesh.getFaceNormal((0 - vVertexes[j].normalindex) - 1); else if (vVertexes[j].normalindex == 0) n = rv->rn.getNormal(); else n = rv->ern[vVertexes[j].normalindex - 1].getNormal(); } // transform normal Point3 &nt = _tm.VectorTransform(n).Normalize(); // encode a normal vector into a 16-bit latitude-longitude value double lng = acos(nt.z) * 255 / (2 * pi); double lat = atan2(nt.y, nt.x) * 255 / (2 * pi); put16((((int)lat & 0xFF) << 8) | ((int)lng & 0xFF), file); } // blend the pivot positions for tag_pivot using mesh's volumes for blending power if (g_tag_for_pivot && !shadow_or_collision) { ExportState("Mesh %s: writing tag_pivot", meshname); Point3 Size = BoxMax - BoxMin; double BoxVolume = pow(Size.x * Size.y * Size.z, 0.333f); // blend matrices float blend = (float)(BoxVolume / (BoxVolume + tag_pivot_volume[current_frame])); float iblend = 1 - blend; tag_pivot_volume[current_frame] = tag_pivot_volume[current_frame] + BoxVolume; Point3 row = _tm.GetRow(3) - _node->GetObjOffsetPos(); tag_pivot_origin[current_frame].x = tag_pivot_origin[current_frame].x * iblend + row.x * blend; tag_pivot_origin[current_frame].y = tag_pivot_origin[current_frame].y * iblend + row.y * blend; tag_pivot_origin[current_frame].z = tag_pivot_origin[current_frame].z * iblend + row.z * blend; } // populate bbox data for frames lFrameBBoxMin[current_frame].x = min(lFrameBBoxMin[current_frame].x, BoxMin.x); lFrameBBoxMin[current_frame].y = min(lFrameBBoxMin[current_frame].y, BoxMin.y); lFrameBBoxMin[current_frame].z = min(lFrameBBoxMin[current_frame].z, BoxMin.z); lFrameBBoxMax[current_frame].x = max(lFrameBBoxMax[current_frame].x, BoxMax.x); lFrameBBoxMax[current_frame].y = max(lFrameBBoxMax[current_frame].y, BoxMax.y); lFrameBBoxMax[current_frame].z = max(lFrameBBoxMax[current_frame].z, BoxMax.z); // delete the working object, if necessary. if (_needsDel) delete _tri; } } // delete if necessary if (needsDel) delete tri; // fill in meshsize pos_current = ftell(file); fseek(file, pos_meshsize, SEEK_SET); put32(pos_current - pos_meshstart, file); fseek(file, pos_current, SEEK_SET); // reset back to first frame SceneEnumProc scratch(ei->theScene, start_time, gi); totalTris += (long)vTriangles.size(); totalVerts += (long)vVertexes.size(); vTriangles.clear(); vVertexes.clear(); } // write tag_pivot ExportState("Writing tag_pivot positions"); if (g_tag_for_pivot) { pos_current = ftell(file); long current_frame = 0; for (range_i = g_frame_ranges.begin(); range_i != g_frame_ranges.end(); range_i++) { for (i = (*range_i).first; i <= (int)(*range_i).last; i++, current_frame++) { fseek(file, pos_tags + totalTags*112*current_frame + (int)lTags.size()*112 + 64, SEEK_SET); // origin putFloat(tag_pivot_origin[current_frame].x, file); putFloat(tag_pivot_origin[current_frame].y, file); putFloat(tag_pivot_origin[current_frame].z, file); } } fseek(file, pos_current, SEEK_SET); } tag_pivot_volume.clear(); tag_pivot_origin.clear(); // write frame data ExportState("Writing culling info"); long current_frame = 0; pos_current = ftell(file); for (range_i = g_frame_ranges.begin(); range_i != g_frame_ranges.end(); range_i++) { for (i = (*range_i).first; i <= (int)(*range_i).last; i++, current_frame++) { fseek(file, pos_framestart + current_frame*56, SEEK_SET); putFloat(lFrameBBoxMin[current_frame].x, file); // bbox min vector putFloat(lFrameBBoxMin[current_frame].y, file); putFloat(lFrameBBoxMin[current_frame].z, file); putFloat(lFrameBBoxMax[current_frame].x, file); // bbox max vector putFloat(lFrameBBoxMax[current_frame].y, file); putFloat(lFrameBBoxMax[current_frame].z, file); putFloat(0, file); // local origin (usually 0 0 0) putFloat(0, file); putFloat(0, file); putFloat(max(lFrameBBoxMin[current_frame].Length(), lFrameBBoxMax[current_frame].Length()) , file); // radius of bounding sphere } } fseek(file, pos_current, SEEK_SET); lFrameBBoxMin.clear(); lFrameBBoxMax.clear(); // fill in filesize pos_current = ftell(file); fseek(file, pos_filesize, SEEK_SET); put32(pos_current, file); fseek(file, pos_current, SEEK_SET); fclose(file); ExportDebug(" total: %i vertexes, %i triangles", totalVerts, totalTris); return TRUE; }
num_put<Pt::Char, ostreambuf_iterator<Pt::Char> >::iter_type num_put<Pt::Char, ostreambuf_iterator<Pt::Char> >::do_put(iter_type s, ios_base& f, char_type fill, long double val) const { putFloat(s, val, f.flags(), f.width(0), fill, f.precision()); return s; }
// gmask is the composite font slot mask // baseindex is to be added to the character (code point) index. jboolean storeGVData(JNIEnv* env, jobject gvdata, jint slot, jint baseIndex, int offset, jobject startPt, int charCount, int glyphCount, hb_glyph_info_t *glyphInfo, hb_glyph_position_t *glyphPos, float devScale) { int i, needToGrow; float x=0, y=0; float startX, startY, advX, advY; float scale = 1.0f / HBFloatToFixedScale / devScale; unsigned int* glyphs; float* positions; int initialCount, glyphArrayLen, posArrayLen, maxGlyphs, storeadv, maxStore; unsigned int* indices; jarray glyphArray, posArray, inxArray; if (!init_JNI_IDs(env)) { return JNI_FALSE; } initialCount = (*env)->GetIntField(env, gvdata, gvdCountFID); do { glyphArray = (jarray)(*env)->GetObjectField(env, gvdata, gvdGlyphsFID); posArray = (jarray)(*env)->GetObjectField(env, gvdata, gvdPositionsFID); inxArray = (jarray)(*env)->GetObjectField(env, gvdata, gvdIndicesFID); if (glyphArray == NULL || posArray == NULL || inxArray == NULL) { JNU_ThrowArrayIndexOutOfBoundsException(env, ""); return JNI_FALSE; } glyphArrayLen = (*env)->GetArrayLength(env, glyphArray); posArrayLen = (*env)->GetArrayLength(env, posArray); maxGlyphs = (charCount > glyphCount) ? charCount : glyphCount; maxStore = maxGlyphs + initialCount; needToGrow = (maxStore > glyphArrayLen) || (maxStore * 2 + 2 > posArrayLen); if (needToGrow) { (*env)->CallVoidMethod(env, gvdata, gvdGrowMID); if ((*env)->ExceptionCheck(env)) { return JNI_FALSE; } } } while (needToGrow); getFloat(env, startPt, &startX, &startY); glyphs = (unsigned int*)(*env)->GetPrimitiveArrayCritical(env, glyphArray, NULL); if (glyphs == NULL) { return JNI_FALSE; } positions = (jfloat*)(*env)->GetPrimitiveArrayCritical(env, posArray, NULL); if (positions == NULL) { (*env)->ReleasePrimitiveArrayCritical(env, glyphArray, glyphs, 0); return JNI_FALSE; } indices = (unsigned int*)(*env)->GetPrimitiveArrayCritical(env, inxArray, NULL); if (indices == NULL) { (*env)->ReleasePrimitiveArrayCritical(env, glyphArray, glyphs, 0); (*env)->ReleasePrimitiveArrayCritical(env, posArray, positions, 0); return JNI_FALSE; } for (i = 0; i < glyphCount; i++) { int storei = i + initialCount; int cluster = glyphInfo[i].cluster - offset; indices[storei] = baseIndex + cluster; glyphs[storei] = (unsigned int)(glyphInfo[i].codepoint | slot); positions[storei*2] = startX + x + glyphPos[i].x_offset * scale; positions[(storei*2)+1] = startY + y - glyphPos[i].y_offset * scale; x += glyphPos[i].x_advance * scale; y -= glyphPos[i].y_advance * scale; storei++; } storeadv = initialCount + glyphCount; // The final slot in the positions array is important // because when the GlyphVector is created from this // data it determines the overall advance of the glyphvector // and this is used in positioning the next glyphvector // during rendering where text is broken into runs. // We also need to report it back into "pt", so layout can // pass it back down for that next run in this code. advX = startX + x; advY = startY + y; positions[(storeadv*2)] = advX; positions[(storeadv*2)+1] = advY; (*env)->ReleasePrimitiveArrayCritical(env, glyphArray, glyphs, 0); (*env)->ReleasePrimitiveArrayCritical(env, posArray, positions, 0); (*env)->ReleasePrimitiveArrayCritical(env, inxArray, indices, 0); putFloat(env, startPt, advX, advY); (*env)->SetIntField(env, gvdata, gvdCountFID, storeadv); return JNI_TRUE; }
bool savePeople (FILE * fp) { onScreenPerson * me = allPeople; int countPeople = 0, a; putSigned (scaleHorizon, fp); putSigned (scaleDivide, fp); while (me) { countPeople ++; me = me -> next; } put2bytes (countPeople, fp); me = allPeople; for (a = 0; a < countPeople; a ++) { putFloat (me -> x, fp); putFloat (me -> y, fp); saveCostume (me -> myPersona, fp); saveAnim (me -> myAnim, fp); fputc (me -> myAnim == me -> lastUsedAnim, fp); putFloat (me -> scale, fp); put2bytes (me -> extra, fp); put2bytes (me -> height, fp); put2bytes (me -> walkToX, fp); put2bytes (me -> walkToY, fp); put2bytes (me -> thisStepX, fp); put2bytes (me -> thisStepY, fp); put2bytes (me -> frameNum, fp); put2bytes (me -> frameTick, fp); put2bytes (me -> walkSpeed, fp); put2bytes (me -> spinSpeed, fp); putSigned (me -> floaty, fp); fputc (me -> show, fp); fputc (me -> walking, fp); fputc (me -> spinning, fp); if (me -> continueAfterWalking) { fputc (1, fp); saveFunction (me -> continueAfterWalking, fp); } else { fputc (0, fp); } put2bytes (me -> direction, fp); put2bytes (me -> angle, fp); put2bytes (me -> angleOffset, fp); put2bytes (me -> wantAngle, fp); putSigned (me -> directionWhenDoneWalking, fp); putSigned (me -> inPoly, fp); putSigned (me -> walkToPoly, fp); fputc (me -> r, fp); fputc (me -> g, fp); fputc (me -> b, fp); fputc (me -> colourmix, fp); fputc (me -> transparency, fp); saveObjectRef (me -> thisType, fp); me = me -> next; } return true; }
void convert(String& str, float value) { str.clear(); putFloat(std::back_inserter(str), value); }
void convert(std::string& str, long double value) { str.clear(); putFloat(std::back_inserter(str), value); }
sp<ByteBuffer> ByteBuffer::putFloat(float value) { putFloat(mPosition, value); mPosition += sizeof(value); return this; }