static void ComputeBounds(int start, int end) { if (start <= end) { int mid = (start + end) / 2, i; Node *T = KDTree[mid]; XMin[T->Id] = YMin[T->Id] = DBL_MAX; XMax[T->Id] = YMax[T->Id] = -DBL_MAX; if (CoordType == THREED_COORDS) { ZMin[T->Id] = DBL_MAX; ZMax[T->Id] = -DBL_MAX; } for (i = start; i <= end; i++) { Node *N = KDTree[i]; if (N == T) continue; if (N->X < XMin[T->Id]) XMin[T->Id] = N->X; if (N->X > XMax[T->Id]) XMax[T->Id] = N->X; if (N->Y < YMin[T->Id]) YMin[T->Id] = N->Y; if (N->Y > YMax[T->Id]) YMax[T->Id] = N->Y; if (CoordType == THREED_COORDS) { if (N->Z < ZMin[T->Id]) ZMin[T->Id] = N->Z; if (N->Z > ZMax[T->Id]) ZMax[T->Id] = N->Z; } } ComputeBounds(start, mid - 1); ComputeBounds(mid + 1, end); } }
void CBeam::OnDataChanged( DataUpdateType_t updateType ) { MarkMessageReceived(); // Make sure that the correct model is referenced for this entity SetModelPointer( modelinfo->GetModel( GetModelIndex() ) ); // Convert weapon world models to viewmodels if they're weapons being carried by the local player for (int i=0;i<MAX_BEAM_ENTS;i++) { C_BaseEntity *pEnt = m_hAttachEntity[i].Get(); if ( pEnt ) { C_BaseCombatWeapon *pWpn = dynamic_cast<C_BaseCombatWeapon *>(pEnt); if ( pWpn && pWpn->IsCarriedByLocalPlayer() ) { C_BasePlayer *player = ToBasePlayer( pWpn->GetOwner() ); C_BaseViewModel *pViewModel = player ? player->GetViewModel( 0 ) : NULL; if ( pViewModel ) { // Get the viewmodel and use it instead m_hAttachEntity.Set( i, pViewModel ); } } } } // Compute the bounds here... Vector mins, maxs; ComputeBounds( mins, maxs ); SetCollisionBounds( mins, maxs ); }
void CEditShape::Attach(CEditShape* from) { ApplyScale (); // transfer data from->ApplyScale (); Fmatrix M = from->_Transform(); M.mulA_43 (_ITransform()); for (ShapeIt it=from->shapes.begin(); it!=from->shapes.end(); it++){ switch (it->type){ case cfSphere:{ Fsphere& T = it->data.sphere; M.transform_tiny(T.P); add_sphere (T); }break; case cfBox:{ Fmatrix B = it->data.box; B.mulA_43 (M); add_box (B); }break; default: THROW; } } // common Scene->RemoveObject (from,true,true); xr_delete (from); ComputeBounds (); }
void CEditShape::add_box(const Fmatrix& B) { shapes.push_back(shape_def()); shapes.back().type = cfBox; shapes.back().data.box.set(B); ComputeBounds(); }
void CEditShape::add_sphere(const Fsphere& S) { shapes.push_back(shape_def()); shapes.back().type = cfSphere; shapes.back().data.sphere.set(S); ComputeBounds(); }
void Canvas::ShiftPosition (Point p) { Surface *surface = GetDeployment ()->GetSurface (); if (surface && IsAttached () && surface->IsTopLevel (this)) { ComputeBounds (); } else { Panel::ShiftPosition (p); } }
void CEditShape::SetScale(const Fvector& val) { if (shapes.size()==1){ switch (shapes[0].type){ case cfSphere:{ FScale.set(val.x,val.x,val.x); }break; case cfBox: FScale.set(val.x,val.y,val.z); break; default: THROW; } }else{ FScale.set(val.x,val.x,val.x); } ComputeBounds (); UpdateTransform (); }
bool CEditShape::Load(IReader& F) { R_ASSERT(F.find_chunk(SHAPE_CHUNK_VERSION)); u16 vers = F.r_u16(); if (SHAPE_CURRENT_VERSION!=vers){ ELog.DlgMsg( mtError, "CEditShape: unsupported version. Object can't load."); return false; } inherited::Load (F); R_ASSERT(F.find_chunk(SHAPE_CHUNK_SHAPES)); shapes.resize (F.r_u32()); F.r (shapes.begin(),shapes.size()*sizeof(shape_def)); ComputeBounds(); return true; }
bool CEditShape::LoadStream(IReader& F) { R_ASSERT(F.find_chunk(SHAPE_CHUNK_VERSION)); u16 vers = F.r_u16(); inherited::LoadStream (F); R_ASSERT(F.find_chunk(SHAPE_CHUNK_SHAPES)); shapes.resize (F.r_u32()); F.r (shapes.begin(),shapes.size()*sizeof(shape_def)); if(F.find_chunk(SHAPE_CHUNK_DATA)) m_shape_type = F.r_u8(); ComputeBounds(); return true; }
void CCheckListBoxItem::Paint(COwnerDrawListBox* pList, LPDRAWITEMSTRUCT pDrawItemStruct) { // Get the DC and rectangle to use. CDC* pDC = CDC::FromHandle(pDrawItemStruct->hDC); if (pDC != NULL) { // Get the colors to use. COLORREF clForeground; COLORREF clBackground; COLORREF clCheckBorder; COLORREF clCheckBackground; COLORREF clCheck; ComputeColors(pList, pDC, pDrawItemStruct, clForeground, clBackground, clCheckBorder, clCheckBackground, clCheck); // Compute the bounding rectangles for the check box and the item. CRect crCheckBox; CRect crItem; ComputeBounds(pList, pDC, pDrawItemStruct, crCheckBox, crItem); // Draw the background. PaintBackground(pList, pDC, pDrawItemStruct, clBackground); // Draw the checkbox. PaintCheckBox(pList, pDC, pDrawItemStruct, crCheckBox, clCheckBorder, clCheckBackground, clCheck); // Draw the item. PaintItem(pList, pDC, pDrawItemStruct, crItem, clForeground, clBackground); // If the item has the focus, draw the focus indicator. if (IsFocused(pList, pDrawItemStruct)) { PaintFocus(pList, pDC, pDrawItemStruct); } } }
bool CEditShape::LoadLTX(CInifile& ini, LPCSTR sect_name) { u32 vers = ini.r_u32(sect_name, "version"); inherited::LoadLTX (ini, sect_name); u32 count = ini.r_u32 (sect_name, "shapes_count"); if(vers>0x0001) m_shape_type = ini.r_u8 (sect_name, "shape_type"); string128 buff; shapes.resize (count); for(u32 i=0; i<count; ++i) { sprintf (buff,"shape_type_%d", i); shapes[i].type = ini.r_u8(sect_name, buff); if(shapes[i].type==CShapeData::cfSphere) { sprintf (buff,"shape_center_%d", i); shapes[i].data.sphere.P = ini.r_fvector3 (sect_name, buff); sprintf (buff,"shape_radius_%d", i); shapes[i].data.sphere.R = ini.r_float (sect_name, buff); }else { R_ASSERT (shapes[i].type==CShapeData::cfBox); sprintf (buff,"shape_matrix_i_%d", i); shapes[i].data.box.i = ini.r_fvector3 (sect_name, buff); sprintf (buff,"shape_matrix_j_%d", i); shapes[i].data.box.j = ini.r_fvector3 (sect_name, buff); sprintf (buff,"shape_matrix_k_%d", i); shapes[i].data.box.k = ini.r_fvector3 (sect_name, buff); sprintf (buff,"shape_matrix_c_%d", i); shapes[i].data.box.c = ini.r_fvector3 (sect_name, buff); } } ComputeBounds(); return true; }
//----------------------------------------------------------------------------- // Purpose: Adds to beam entity list //----------------------------------------------------------------------------- void CBeam::AddEntity( void ) { // If set to invisible, skip. Do this before resetting the entity pointer so it has // valid data to decide whether it's visible. if ( !ShouldDraw() ) { return; } //FIXME: If we're hooked up to an attachment point, then recompute our bounds every frame if ( m_hAttachEntity[0].Get() || m_hAttachEntity[1].Get() ) { // Compute the bounds here... Vector mins, maxs; ComputeBounds( mins, maxs ); SetCollisionBounds( mins, maxs ); } MoveToLastReceivedPosition(); }
void CEditShape::ApplyScale() { for (ShapeIt it=shapes.begin(); it!=shapes.end(); it++){ switch (it->type){ case cfSphere:{ Fsphere& T = it->data.sphere; FTransformS.transform_tiny(T.P); T.R *= PScale.x; }break; case cfBox:{ Fmatrix& B = it->data.box; B.mulA_43 (FTransformS); }break; } } FScale.set (1.f,1.f,1.f); UpdateTransform (true); ComputeBounds (); }
void CEditShape::Detach() { if (shapes.size()>1){ Select (true); ApplyScale (); // create scene shapes const Fmatrix& M = _Transform(); ShapeIt it=shapes.begin(); it++; for (; it!=shapes.end(); it++){ string256 namebuffer; Scene->GenObjectName (OBJCLASS_SHAPE, namebuffer, Name); CEditShape* shape = (CEditShape*)Scene->GetOTool(ClassID)->CreateObject(0, namebuffer); switch (it->type){ case cfSphere:{ Fsphere T = it->data.sphere; M.transform_tiny(T.P); shape->PPosition= T.P; T.P.set (0,0,0); shape->add_sphere(T); }break; case cfBox:{ Fmatrix B = it->data.box; B.mulA_43 (M); shape->PPosition= B.c; B.c.set (0,0,0); shape->add_box (B); }break; default: THROW; } Scene->AppendObject (shape,false); shape->Select (true); } // erase shapes in base object it=shapes.begin(); it++; shapes.erase(it,shapes.end()); ComputeBounds(); Scene->UndoSave(); } }
CStatMeshViewer::CStatMeshViewer(CStaticMesh* Mesh0, CApplication* Window) : CMeshViewer(Mesh0->OriginalMesh, Window) , Mesh(Mesh0) { guard(CStatMeshViewer::CStatMeshViewer); CStatMeshInstance *StatInst = new CStatMeshInstance(); StatInst->SetMesh(Mesh); Inst = StatInst; #if 0 // compute model center CVec3 offset; offset[0] = (Mesh->BoundingBox.Max.X + Mesh->BoundingBox.Min.X) / 2; offset[1] = (Mesh->BoundingBox.Max.Y + Mesh->BoundingBox.Min.Y) / 2; offset[2] = (Mesh->BoundingBox.Max.Z + Mesh->BoundingBox.Min.Z) / 2; offset[2] += Mesh->BoundingSphere.R / 20; // offset a bit up SetViewOffset(offset); // automatically scale view distance depending on model size SetDistScale(Mesh->BoundingSphere.R / 150); #else //?? if Lods.Count > 0 && Lods[0].Verts.Num() > 0 CVec3 Mins, Maxs; if (Mesh0->Lods.Num()) { const CStaticMeshLod &Lod = Mesh0->Lods[0]; ComputeBounds(&Lod.Verts[0].Position, Lod.NumVerts, sizeof(CStaticMeshVertex), Mins, Maxs); } else { Mins = Maxs = nullVec3; } InitViewerPosition(Mins, Maxs); #endif unguard; }
//! 显示数据 void CViewerWnd::OnDraw(CDC* pDC, const CRect& rcClient) { if((rcClient.Width()<1) || (rcClient.Height()<1)) { return; } if(OGDCIS0(m_drawing.m_dCoordRatio)) { return; } if(m_drawing.m_rcClient != rcClient) { m_drawing.ChangeClient(rcClient); m_bRefresh = TRUE; } OgdcRect2D rcBounds = ComputeBounds(); if(m_drawing.m_rcBounds != rcBounds) { m_drawing.m_rcBounds = rcBounds; m_bRefresh = TRUE; } BOOL bDeviceChange = FALSE; LONG ncxFullScreen = GetSystemMetrics( SM_CXFULLSCREEN ); LONG ncyFullScreen = GetSystemMetrics( SM_CYFULLSCREEN ); if(m_bitmap.m_hObject != NULL) { BITMAP BM; m_bitmap.GetBitmap(&BM); if(BM.bmWidth != ncxFullScreen || BM.bmHeight != ncyFullScreen || pDC->GetDeviceCaps(BITSPIXEL) != BM.bmBitsPixel) { bDeviceChange = TRUE; m_bRefresh = TRUE; } } if(pDC->IsPrinting() || m_bRefresh) { if(!pDC->IsPrinting() && bDeviceChange && m_pOldBitmap != NULL) { m_memDC.SelectObject(m_pOldBitmap); m_pOldBitmap = NULL; m_bitmap.DeleteObject(); m_memDC.DeleteDC(); } if(!pDC->IsPrinting() && m_bitmap.m_hObject == NULL) { m_memDC.CreateCompatibleDC(pDC); if(!m_bitmap.CreateCompatibleBitmap(pDC, ncxFullScreen, ncyFullScreen)) { m_bRefresh = FALSE; return; } m_pOldBitmap = m_memDC.SelectObject(&m_bitmap); } CDC* pDeviceDC = pDC; if(!pDC->IsPrinting()) { pDeviceDC = &m_memDC; } //! 画背景矩形 CBrush brush(RGB(255,255,255)); pDeviceDC->FillRect(rcClient, &brush); //! 画数据 for(int i=0;i<m_datasets.GetSize();i++) { OgdcStyle style = m_styles[i]; OgdcDataset* pDT = m_datasets.GetAt(i); CPen pen(PS_SOLID, style.m_nLineWidth, style.m_clrLine); CPen* pOldPen = pDeviceDC->SelectObject(&pen); CBrush brush(style.m_clrFillFore); CBrush* pOldBrush = NULL; if(style.m_nFillStyle == 1) { pOldBrush = (CBrush*)pDeviceDC->SelectStockObject(NULL_BRUSH); } else { pOldBrush = pDeviceDC->SelectObject(&brush); } m_drawing.m_curStyle = style; m_drawing.DrawDataset(pDeviceDC, m_datasets[i]); pDeviceDC->SelectObject(pOldPen); pDeviceDC->SelectObject(pOldBrush); } m_bRefresh = FALSE; } if(!pDC->IsPrinting() && m_bitmap.m_hObject != NULL) { pDC->BitBlt(rcClient.left, rcClient.top, rcClient.Width(), rcClient.Height(), &m_memDC, rcClient.left, rcClient.top, SRCCOPY ); } //! 画选择 if(m_nSelectID >= 0 && m_pSelectDataset != NULL && !pDC->IsPrinting()) { OgdcDatasetVector* pDatasetV = m_pSelectDataset; OgdcQueryDef queryDef; queryDef.m_nType = OgdcQueryDef::IDs; queryDef.m_nOptions = OgdcQueryDef::Geometry; queryDef.m_nCursorType = OgdcQueryDef::OpenStatic; queryDef.m_nCursorLocation = OgdcQueryDef::UseClient; queryDef.m_IDs.Add(m_nSelectID); OgdcRecordset* pRecordset = pDatasetV->Query(queryDef); if(pRecordset != NULL) { pRecordset->Move(OgdcRecordset::End, 0); if (pDatasetV->GetType() == OgdcDataset::PointEPS || pDatasetV->GetType() == OgdcDataset::LineEPS || pDatasetV->GetType() == OgdcDataset::RegionEPS || pDatasetV->GetType() == OgdcDataset::TextEPS) { UGC::UGGeometry* pGeometry = NULL; while(!pRecordset->IsBOF()) { if(pRecordset->GetElement(pGeometry) && pGeometry != NULL) { CPen pen(PS_SOLID, 2, RGB(0,0,255)); CPen* pOldPen = pDC->SelectObject(&pen); CBrush brush(RGB(255,255,115)); CBrush *pOldBrush = pDC->SelectObject(&brush); m_drawing.DrawElement(pDC, pGeometry, true); pDC->SelectObject(pOldPen); pDC->SelectObject(pOldBrush); delete pGeometry; pGeometry = NULL; break; } pRecordset->Move(OgdcRecordset::Current, -1); if(pGeometry != NULL) { delete pGeometry; pGeometry = NULL; } } } else { OgdcElement* pElement = NULL; while(!pRecordset->IsBOF()) { if(pRecordset->GetElement(pElement) && pElement != NULL) { CPen pen(PS_SOLID, 2, RGB(0,0,255)); CPen* pOldPen = pDC->SelectObject(&pen); CBrush brush(RGB(255,255,115)); CBrush *pOldBrush = pDC->SelectObject(&brush); m_drawing.DrawElement(pDC, pElement, true); pDC->SelectObject(pOldPen); pDC->SelectObject(pOldBrush); delete pElement; pElement = NULL; break; } pRecordset->Move(OgdcRecordset::Current, -1); if(pElement != NULL) { delete pElement; pElement = NULL; } } } pDatasetV->ReleaseRecordset(pRecordset); pRecordset = NULL; } } }
CSkelMeshViewer::CSkelMeshViewer(CSkeletalMesh* Mesh0, CApplication* Window) : CMeshViewer(Mesh0->OriginalMesh, Window) , Mesh(Mesh0) , AnimIndex(-1) , IsFollowingMesh(false) , ShowSkel(0) , ShowLabels(false) , ShowAttach(false) , ShowUV(false) { CSkelMeshInstance *SkelInst = new CSkelMeshInstance(); SkelInst->SetMesh(Mesh); if (GForceAnimSet) { CAnimSet *AttachAnim = GetAnimSet(GForceAnimSet); if (!AttachAnim) { appPrintf("WARNING: specified wrong AnimSet (%s class) object to attach\n", GForceAnimSet->GetClassName()); GForceAnimSet = NULL; } if (AttachAnim) SkelInst->SetAnim(AttachAnim); } else if (Mesh->OriginalMesh->IsA("SkeletalMesh")) // UE2 class { const USkeletalMesh *OriginalMesh = static_cast<USkeletalMesh*>(Mesh->OriginalMesh); if (OriginalMesh->Animation) SkelInst->SetAnim(OriginalMesh->Animation->ConvertedAnim); } Inst = SkelInst; // compute bounds for the current mesh CVec3 Mins, Maxs; if (Mesh0->Lods.Num()) { const CSkelMeshLod &Lod = Mesh0->Lods[0]; ComputeBounds(&Lod.Verts[0].Position, Lod.NumVerts, sizeof(CSkelMeshVertex), Mins, Maxs); // ... transform bounds SkelInst->BaseTransformScaled.TransformPointSlow(Mins, Mins); SkelInst->BaseTransformScaled.TransformPointSlow(Maxs, Maxs); } else { Mins = Maxs = nullVec3; } // extend bounds with additional meshes for (int i = 0; i < TaggedMeshes.Num(); i++) { CSkelMeshInstance* Inst = TaggedMeshes[i]; if (Inst->pMesh != SkelInst->pMesh) { const CSkeletalMesh *Mesh2 = Inst->pMesh; // the same code for Inst CVec3 Bounds2[2]; const CSkelMeshLod &Lod2 = Mesh2->Lods[0]; ComputeBounds(&Lod2.Verts[0].Position, Lod2.NumVerts, sizeof(CSkelMeshVertex), Bounds2[0], Bounds2[1]); Inst->BaseTransformScaled.TransformPointSlow(Bounds2[0], Bounds2[0]); Inst->BaseTransformScaled.TransformPointSlow(Bounds2[1], Bounds2[1]); ComputeBounds(Bounds2, 2, sizeof(CVec3), Mins, Maxs, true); // include Bounds2 into Mins/Maxs } // reset animation for all meshes TaggedMeshes[i]->TweenAnim(NULL, 0); } InitViewerPosition(Mins, Maxs); #if HIGHLIGHT_CURRENT TimeSinceCreate = -2; // ignore first 2 frames: 1st frame will be called after mesh changing, 2nd frame could load textures etc #endif #if SHOW_BOUNDS appPrintf("Bounds.min = %g %g %g\n", FVECTOR_ARG(Mesh->BoundingBox.Min)); appPrintf("Bounds.max = %g %g %g\n", FVECTOR_ARG(Mesh->BoundingBox.Max)); appPrintf("Origin = %g %g %g\n", FVECTOR_ARG(Mesh->MeshOrigin)); appPrintf("Sphere = %g %g %g R=%g\n", FVECTOR_ARG(Mesh->BoundingSphere), Mesh->BoundingSphere.R); appPrintf("Offset = %g %g %g\n", VECTOR_ARG(offset)); #endif // SHOW_BOUNDS }
static void ExportSection(ExportContext& Context, const CBaseMeshLod& Lod, const CMeshVertex* Verts, int SectonIndex, FArchive& Ar) { guard(ExportSection); int VertexSize = Context.IsSkeletal() ? sizeof(CSkelMeshVertex) : sizeof(CStaticMeshVertex); const CMeshSection& S = Lod.Sections[SectonIndex]; bool bLast = (SectonIndex == Lod.Sections.Num()-1); // Remap section indices to local indices CIndexBuffer::IndexAccessor_t GetIndex = Lod.Indices.GetAccessor(); TArray<int> indexRemap; // old vertex index -> new vertex index indexRemap.Init(-1, Lod.NumVerts); int numLocalVerts = 0; int numLocalIndices = S.NumFaces * 3; for (int idx = 0; idx < numLocalIndices; idx++) { int vertIndex = GetIndex(S.FirstIndex + idx); if (indexRemap[vertIndex] == -1) { indexRemap[vertIndex] = numLocalVerts++; } } // Prepare buffers int IndexBufIndex = Context.Data.AddZeroed(); int PositionBufIndex = Context.Data.AddZeroed(); int NormalBufIndex = Context.Data.AddZeroed(); int TangentBufIndex = Context.Data.AddZeroed(); int BonesBufIndex = -1; int WeightsBufIndex = -1; if (Context.IsSkeletal()) { BonesBufIndex = Context.Data.AddZeroed(); WeightsBufIndex = Context.Data.AddZeroed(); } int UVBufIndex[MAX_MESH_UV_SETS]; for (int i = 0; i < Lod.NumTexCoords; i++) { UVBufIndex[i] = Context.Data.AddZeroed(); } BufferData& IndexBuf = Context.Data[IndexBufIndex]; BufferData& PositionBuf = Context.Data[PositionBufIndex]; BufferData& NormalBuf = Context.Data[NormalBufIndex]; BufferData& TangentBuf = Context.Data[TangentBufIndex]; BufferData* UVBuf[MAX_MESH_UV_SETS]; BufferData* BonesBuf = NULL; BufferData* WeightsBuf = NULL; PositionBuf.Setup(numLocalVerts, "VEC3", BufferData::FLOAT, sizeof(CVec3)); NormalBuf.Setup(numLocalVerts, "VEC3", BufferData::FLOAT, sizeof(CVec3)); TangentBuf.Setup(numLocalVerts, "VEC4", BufferData::FLOAT, sizeof(CVec4)); for (int i = 0; i < Lod.NumTexCoords; i++) { UVBuf[i] = &Context.Data[UVBufIndex[i]]; UVBuf[i]->Setup(numLocalVerts, "VEC2", BufferData::FLOAT, sizeof(CMeshUVFloat)); } if (Context.IsSkeletal()) { BonesBuf = &Context.Data[BonesBufIndex]; WeightsBuf = &Context.Data[WeightsBufIndex]; BonesBuf->Setup(numLocalVerts, "VEC4", BufferData::UNSIGNED_SHORT, sizeof(uint16)*4); WeightsBuf->Setup(numLocalVerts, "VEC4", BufferData::UNSIGNED_BYTE, sizeof(uint32), /*InNormalized=*/ true); } // Prepare and build indices TArray<int> localIndices; localIndices.AddUninitialized(numLocalIndices); int* pIndex = localIndices.GetData(); for (int i = 0; i < numLocalIndices; i++) { *pIndex++ = GetIndex(S.FirstIndex + i); } if (numLocalVerts <= 65536) { IndexBuf.Setup(numLocalIndices, "SCALAR", BufferData::UNSIGNED_SHORT, sizeof(uint16)); for (int idx = 0; idx < numLocalIndices; idx++) { IndexBuf.Put<uint16>(indexRemap[localIndices[idx]]); } } else { IndexBuf.Setup(numLocalIndices, "SCALAR", BufferData::UNSIGNED_INT, sizeof(uint32)); for (int idx = 0; idx < numLocalIndices; idx++) { IndexBuf.Put<uint32>(indexRemap[localIndices[idx]]); } } // Build reverse index map for fast lookup of vertex by its new index. // It maps new vertex index to old vertex index. TArray<int> revIndexMap; revIndexMap.AddUninitialized(numLocalVerts); for (int i = 0; i < indexRemap.Num(); i++) { int newIndex = indexRemap[i]; if (newIndex != -1) { revIndexMap[newIndex] = i; } } // Build vertices for (int i = 0; i < numLocalVerts; i++) { int vertIndex = revIndexMap[i]; const CMeshVertex& V = VERT(vertIndex); CVec3 Position = V.Position; CVec4 Normal, Tangent; Unpack(Normal, V.Normal); Unpack(Tangent, V.Tangent); // Unreal (and we are) using normal.w for computing binormal. glTF // uses tangent.w for that. Make this value exactly 1.0 of -1.0 to make glTF // validator happy. #if 0 // There's some problem: V.Normal.W == 0x80 -> -1.008 instead of -1.0 if (Normal.w > 1.001 || Normal.w < -1.001) { appError("%X -> %g\n", V.Normal.Data, Normal.w); } #endif Tangent.w = (Normal.w < 0) ? -1 : 1; TransformPosition(Position); TransformDirection(Normal); TransformDirection(Tangent); Normal.Normalize(); Tangent.Normalize(); // Fill buffers PositionBuf.Put(Position); NormalBuf.Put(Normal.xyz); TangentBuf.Put(Tangent); UVBuf[0]->Put(V.UV); } // Compute bounds for PositionBuf CVec3 Mins, Maxs; ComputeBounds((CVec3*)PositionBuf.Data, numLocalVerts, sizeof(CVec3), Mins, Maxs); char buf[256]; appSprintf(ARRAY_ARG(buf), "[ %g, %g, %g ]", VECTOR_ARG(Mins)); PositionBuf.BoundsMin = buf; appSprintf(ARRAY_ARG(buf), "[ %g, %g, %g ]", VECTOR_ARG(Maxs)); PositionBuf.BoundsMax = buf; if (Context.IsSkeletal()) { for (int i = 0; i < numLocalVerts; i++) { int vertIndex = revIndexMap[i]; const CMeshVertex& V0 = VERT(vertIndex); const CSkelMeshVertex& V = static_cast<const CSkelMeshVertex&>(V0); int16 Bones[NUM_INFLUENCES]; static_assert(NUM_INFLUENCES == 4, "Code designed for 4 influences"); static_assert(sizeof(Bones) == sizeof(V.Bone), "Unexpected V.Bones size"); memcpy(Bones, V.Bone, sizeof(Bones)); for (int j = 0; j < NUM_INFLUENCES; j++) { // We have INDEX_NONE as list terminator, should replace with something else for glTF if (Bones[j] == INDEX_NONE) { Bones[j] = 0; } } BonesBuf->Put(*(uint64*)&Bones); WeightsBuf->Put(V.PackedWeights); } } // Secondary UVs for (int uvIndex = 1; uvIndex < Lod.NumTexCoords; uvIndex++) { BufferData* pBuf = UVBuf[uvIndex]; const CMeshUVFloat* srcUV = Lod.ExtraUV[uvIndex-1]; for (int i = 0; i < numLocalVerts; i++) { int vertIndex = revIndexMap[i]; pBuf->Put(srcUV[vertIndex]); } } // Write primitive information to json Ar.Printf( " {\n" " \"attributes\" : {\n" " \"POSITION\" : %d,\n" " \"NORMAL\" : %d,\n" " \"TANGENT\" : %d,\n", PositionBufIndex, NormalBufIndex, TangentBufIndex ); if (Context.IsSkeletal()) { Ar.Printf( " \"JOINTS_0\" : %d,\n" " \"WEIGHTS_0\" : %d,\n", BonesBufIndex, WeightsBufIndex ); } for (int i = 0; i < Lod.NumTexCoords; i++) { Ar.Printf( " \"TEXCOORD_%d\" : %d%s\n", i, UVBufIndex[i], i < (Lod.NumTexCoords-1) ? "," : "" ); } Ar.Printf( " },\n" " \"indices\" : %d,\n" " \"material\" : %d\n" " }%s\n", IndexBufIndex, SectonIndex, SectonIndex < (Lod.Sections.Num()-1) ? "," : "" ); unguard; }
void CreateQuadrantCandidateSet(int K) { Node *From, *To; Candidate *NFrom; int L, Q, CandPerQ, Added, Count, i; if (K <= 0) return; if (TraceLevel >= 2) printff("Creating quadrant candidate set ... "); KDTree = BuildKDTree(1); assert(XMin = (double *) malloc((1 + DimensionSaved) * sizeof(double))); assert(XMax = (double *) malloc((1 + DimensionSaved) * sizeof(double))); assert(YMin = (double *) malloc((1 + DimensionSaved) * sizeof(double))); assert(YMax = (double *) malloc((1 + DimensionSaved) * sizeof(double))); if (CoordType == THREED_COORDS) { assert(ZMin = (double *) malloc((1 + DimensionSaved) * sizeof(double))); assert(ZMax = (double *) malloc((1 + DimensionSaved) * sizeof(double))); } ComputeBounds(0, Dimension - 1); Contains = CoordType == THREED_COORDS ? Contains3D : Contains2D; BoxOverlaps = CoordType == THREED_COORDS ? BoxOverlaps3D : BoxOverlaps2D; L = CoordType == THREED_COORDS ? 8 : 4; CandPerQ = K / L; assert(CandidateSet = (Candidate *) malloc((K + 1) * sizeof(Candidate))); From = FirstNode; do { Count = 0; for (NFrom = From->CandidateSet; NFrom && NFrom->To; NFrom++) if (FixedOrCommon(From, NFrom->To) && ++Count == 2) break; if (Count == 2) continue; Added = 0; for (Q = 1; Q <= L; Q++) { NearestQuadrantNeighbors(From, Q, CandPerQ); for (i = 0; i < Candidates; i++) { To = CandidateSet[i].To; if (AddCandidate(From, To, D(From, To), 1)) Added++; } } if (K > Added) { NearestQuadrantNeighbors(From, 0, K - Added); for (i = 0; i < Candidates; i++) { To = CandidateSet[i].To; AddCandidate(From, To, D(From, To), 2); } } } while ((From = From->Suc) != FirstNode); free(CandidateSet); free(KDTree); free(XMin); free(XMax); free(YMin); free(YMax); if (CoordType == THREED_COORDS) { free(ZMin); free(ZMax); } if (Level == 0 && (WeightType == GEO || WeightType == GEOM || WeightType == GEO_MEEUS || WeightType == GEOM_MEEUS)) { Candidate **SavedCandidateSet; assert(SavedCandidateSet = (Candidate **) malloc((1 + DimensionSaved) * sizeof(Candidate *))); if (TraceLevel >= 2) printff("done\n"); From = FirstNode; while ((From = From->Suc) != FirstNode) if ((From->Y > 0) != (FirstNode->Y > 0)) break; if (From != FirstNode) { /* Transform longitude (180 and -180 map to 0) */ From = FirstNode; do { SavedCandidateSet[From->Id] = From->CandidateSet; From->CandidateSet = 0; From->Zc = From->Y; if (WeightType == GEO || WeightType == GEO_MEEUS) From->Y = (int) From->Y + 5.0 * (From->Y - (int) From->Y) / 3.0; From->Y += From->Y > 0 ? -180 : 180; if (WeightType == GEO || WeightType == GEO_MEEUS) From->Y = (int) From->Y + 3.0 * (From->Y - (int) From->Y) / 5.0; } while ((From = From->Suc) != FirstNode); Level++; CreateQuadrantCandidateSet(K); Level--; From = FirstNode; do From->Y = From->Zc; while ((From = From->Suc) != FirstNode); do { Candidate *QCandidateSet = From->CandidateSet; From->CandidateSet = SavedCandidateSet[From->Id]; for (NFrom = QCandidateSet; (To = NFrom->To); NFrom++) AddCandidate(From, To, NFrom->Cost, NFrom->Alpha); free(QCandidateSet); } while ((From = From->Suc) != FirstNode); free(SavedCandidateSet); } } if (Level == 0) { ResetCandidateSet(); AddTourCandidates(); if (CandidateSetSymmetric) SymmetrizeCandidateSet(); if (TraceLevel >= 2) printff("done\n"); } }
void CreateNearestNeighborCandidateSet(int K) { Node *From, *To; int i; if (TraceLevel >= 2) printff("Creating nearest neighbor candidate set ... "); KDTree = BuildKDTree(1); assert(XMin = (double *) malloc((1 + DimensionSaved) * sizeof(double))); assert(XMax = (double *) malloc((1 + DimensionSaved) * sizeof(double))); assert(YMin = (double *) malloc((1 + DimensionSaved) * sizeof(double))); assert(YMax = (double *) malloc((1 + DimensionSaved) * sizeof(double))); if (CoordType == THREED_COORDS) { assert(ZMin = (double *) malloc((1 + DimensionSaved) * sizeof(double))); assert(ZMax = (double *) malloc((1 + DimensionSaved) * sizeof(double))); } ComputeBounds(0, Dimension - 1); Contains = CoordType == THREED_COORDS ? Contains3D : Contains2D; BoxOverlaps = CoordType == THREED_COORDS ? BoxOverlaps3D : BoxOverlaps2D; assert(CandidateSet = (Candidate *) malloc((K + 1) * sizeof(Candidate))); From = FirstNode; do { NearestQuadrantNeighbors(From, 0, K); for (i = 0; i < Candidates; i++) { To = CandidateSet[i].To; AddCandidate(From, To, D(From, To), 1); } } while ((From = From->Suc) != FirstNode); free(CandidateSet); free(KDTree); free(XMin); free(XMax); free(YMin); free(YMax); if (CoordType == THREED_COORDS) { free(ZMin); free(ZMax); } if (Level == 0 && (WeightType == GEOM || WeightType == GEOM_MEEUS)) { Candidate **SavedCandidateSet; assert(SavedCandidateSet = (Candidate **) malloc((1 + DimensionSaved) * sizeof(Candidate *))); if (TraceLevel >= 2) printff("done\n"); /* Transform longitude (180 and -180 map to 0) */ From = FirstNode; do { SavedCandidateSet[From->Id] = From->CandidateSet; From->CandidateSet = 0; From->Yc = From->Y; From->Y += From->Y > 0 ? -180 : 180; } while ((From = From->Suc) != FirstNode); Level++; CreateNearestNeighborCandidateSet(K); Level--; From = FirstNode; do From->Y = From->Yc; while ((From = From->Suc) != FirstNode); do { Candidate *QCandidateSet = From->CandidateSet; Candidate *NFrom; From->CandidateSet = SavedCandidateSet[From->Id]; for (NFrom = QCandidateSet; (To = NFrom->To); NFrom++) AddCandidate(From, To, NFrom->Cost, NFrom->Alpha); free(QCandidateSet); } while ((From = From->Suc) != FirstNode); free(SavedCandidateSet); } if (Level == 0) { ResetCandidateSet(); AddTourCandidates(); if (CandidateSetSymmetric) SymmetrizeCandidateSet(); if (TraceLevel >= 2) printff("done\n"); } }
void CViewerWnd::AddDataset(OgdcDataset* pDataset, OgdcStyle& style, OgdcString& strName, BOOL bClear) { if(pDataset == NULL) { return; } if(bClear) { m_nSelectID = -1; m_pSelectDataset = NULL; m_datasets.RemoveAll(); m_styles.RemoveAll(); m_names.RemoveAll(); } else if(FindDataset(pDataset) != -1) { return; } if(pDataset->GetType() == OgdcDataset::Tabular || strName.IsEmpty()) { return; } m_datasets.Add(pDataset); m_styles.Add(style); m_names.Add(strName); m_drawing.m_rcBounds = ComputeBounds(); if(m_datasets.GetSize() == 1) { m_drawing.ViewEntire(); if(!pDataset->IsRaster()) { OgdcDatasetVector* pDatasetV = (OgdcDatasetVector*)pDataset; long nCount = pDatasetV->GetObjectCount(); if(nCount > 1000000) //! 百万以上 { m_drawing.Zoom(100); } else if(nCount > 100000) //! 十万以上 { m_drawing.Zoom(32); } else if(nCount > 10000) //! 一万以上 { m_drawing.Zoom(8); } else if(nCount > 3000) //! 三千以上 { m_drawing.Zoom(2); } } else { OgdcDatasetRaster *pDatasetR = (OgdcDatasetRaster *)pDataset; double dWidth = m_drawing.m_rcBounds.Width(); double dHeight = m_drawing.m_rcBounds.Height(); LONG nWidth = pDatasetR->GetWidth(); LONG nHeight = pDatasetR->GetHeight(); if(nWidth!=0 && nHeight!=0) { double dResolutionX = dWidth / nWidth; double dResolutionY = dHeight / nHeight; if(dResolutionX > dResolutionY) { m_drawing.SetCoordRatio(dResolutionX); } else { m_drawing.SetCoordRatio(dResolutionY); } } } } }