void PanelElement::AddGeometry (MESHHANDLE hMesh, DWORD grpidx, const NTVERTEX *vtx, DWORD nvtx, const WORD *idx, DWORD nidx) { mesh = hMesh; gidx = grpidx; grp = oapiMeshGroup (hMesh, grpidx); vtxofs = grp->nVtx; oapiAddMeshGroupBlock (hMesh, grpidx, vtx, nvtx, idx, nidx); }
// -------------------------------------------------------------- // Set up the dynamic elastic sail deformation code // -------------------------------------------------------------- void SolarSail::SetupElasticity (MESHHANDLE hMesh) { MESHGROUP *sail = oapiMeshGroup (hMesh, GRP_sail1); // all sail segments have the same mesh structure, so segment 1 represents all 4 DWORD nvtx = sail->nVtx/2; // scan front side only DWORD nidx = sail->nIdx/2; // scan front side only DWORD ntri = nidx/3; WORD *idx = sail->Idx; NTVERTEX *vtx = sail->Vtx; DWORD i, j, k, m, nj, nk; // generate node neighbour graph sail_vbuf = new VECTOR3[nvtx]; nbhr = new NBHR[nvtx]; for (i = 0; i < nvtx; i++) { nbhr[i].nnd = 0; nbhr[i].fix = (vtx[i].x == 0 || vtx[i].y == 0); } for (i = 0; i < ntri; i++) { WORD *tri = idx+(i*3); for (j = 0; j < 3; j++) { nj = tri[j]; for (k = 0; k < 3; k++) { if (j == k) continue; nk = tri[k]; for (m = 0; m < nbhr[nj].nnd; m++) if (nbhr[nj].nd[m] == nk) break; // already in neighbour list if (m == nbhr[nj].nnd) { if (nbhr[nj].nnd == MAXNBHR) strcpy (oapiDebugString(), "Problems!"); else { nbhr[nj].nd[m] = nk; nbhr[nj].dst0[m] = Dst (vtx+nj, vtx+nk); nbhr[nj].nnd++; } } } } } sail_nvtx = nvtx; sail_ntri = ntri; }
// -------------------------------------------------------------- // Update sail nodal displacements // -------------------------------------------------------------- void SolarSail::UpdateSail (const VECTOR3 *rpressure) { // A kind of poor man's finite element code. Should eventually be done properly! static int sailidx = 0; const double elast = 1e-1; const double pscale = 1e3; DWORD i, j; NBHR *nb; NTVERTEX *vi, *vj; VECTOR3 dv, F, nm; static VECTOR3 *nml = 0; static DWORD *nsd = 0; double dst; sailidx = ++sailidx % 4; MESHGROUP *sail = oapiMeshGroup (hMesh, sailidx); for (i = 0; i < sail_nvtx; i++) { F = _V(0,0,rpressure->z*pscale); // note - should be calculated for LOCAL normal vi = sail->Vtx+i; nb = nbhr+i; if (nb->fix) { sail_vbuf[i] = _V(0,0,0); continue; } for (j = 0; j < nb->nnd; j++) { vj = sail->Vtx+nb->nd[j]; dv.x = vj->x - vi->x; dv.y = vj->y - vi->y; dv.z = vj->z - vi->z; dst = length(dv); if (dst > nb->dst0[j]) { // is stretched F += dv*(elast/nb->dst0[j]); } } sail_vbuf[i] = F; } for (i = 0; i < sail_nvtx; i++) { sail->Vtx[i].x += (float)sail_vbuf[i].x; sail->Vtx[i].y += (float)sail_vbuf[i].y; sail->Vtx[i].z += (float)sail_vbuf[i].z; } for (i = 0; i < sail_nvtx; i++) { sail->Vtx[i+sail_nvtx].x += (float)sail_vbuf[i].x; sail->Vtx[i+sail_nvtx].y += (float)sail_vbuf[i].y; sail->Vtx[i+sail_nvtx].z += (float)sail_vbuf[i].z; } // calculate smooth normals - surely this could be done more efficiently! if (!nml) { nml = new VECTOR3[sail_nvtx]; nsd = new DWORD[sail_nvtx]; } memset (nml, 0, sail_nvtx*sizeof(VECTOR3)); memset (nsd, 0, sail_nvtx*sizeof(DWORD)); for (i = 0; i < sail_ntri; i++) { WORD *idx = sail->Idx + i*3; nm = Nml(sail->Vtx + *idx, sail->Vtx + *(idx+1), sail->Vtx + *(idx+2)); for (j = 0; j < 3; j++) { nml[*(idx+j)] += unit(nm); nsd[*(idx+j)]++; } } for (i = 0; i < sail_nvtx; i++) { sail->Vtx[i].nx = (float)nml[i].x/nsd[i]; sail->Vtx[i].ny = (float)nml[i].y/nsd[i]; sail->Vtx[i].nz = (float)nml[i].z/nsd[i]; } for (i = 0; i < sail_nvtx; i++) { sail->Vtx[i+sail_nvtx].nx = -(float)nml[i].x/nsd[i]; sail->Vtx[i+sail_nvtx].ny = -(float)nml[i].y/nsd[i]; sail->Vtx[i+sail_nvtx].nz = -(float)nml[i].z/nsd[i]; } }
void WheelbrakeLever::Reset2D (MESHHANDLE hMesh) { grp = oapiMeshGroup (hMesh, GRP_INSTRUMENTS_ABOVE_P0); vtxofs = 104; }
void GearIndicator::Reset2D (MESHHANDLE hMesh) { grp = oapiMeshGroup (hMesh, GRP_INSTRUMENTS_ABOVE_P0); vtxofs = 72; }
void GearLever::Reset2D (MESHHANDLE hMesh) { grp = oapiMeshGroup (hMesh, GRP_INSTRUMENTS_ABOVE_P0); vtxofs = 68; }
void DGButton3::Reset2D (MESHHANDLE hMesh) { grp = oapiMeshGroup (hMesh, mgrp); }
void DGSwitch1::DefineAnimation2D (MESHHANDLE hMesh, DWORD meshgrp, int vtxofs) { grp = oapiMeshGroup (hMesh, meshgrp); mgrp = meshgrp; vofs = vtxofs; }
void DGSwitch2::Reset2D (MESHHANDLE hMesh) { grp = oapiMeshGroup (hMesh, mgrp); }