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);
    }
}
Ejemplo n.º 2
0
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 );
}
Ejemplo n.º 3
0
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			();
}
Ejemplo n.º 4
0
void CEditShape::add_box(const Fmatrix& B)
{
	shapes.push_back(shape_def());
	shapes.back().type	= cfBox;
	shapes.back().data.box.set(B);

	ComputeBounds();
}
Ejemplo n.º 5
0
void CEditShape::add_sphere(const Fsphere& S)
{
	shapes.push_back(shape_def());
	shapes.back().type	= cfSphere;
	shapes.back().data.sphere.set(S);

	ComputeBounds();
}
Ejemplo n.º 6
0
void
Canvas::ShiftPosition (Point p)
{
	Surface *surface = GetDeployment ()->GetSurface ();
	if (surface && IsAttached () && surface->IsTopLevel (this)) {
		ComputeBounds ();
	} else {
		Panel::ShiftPosition (p);
	}
} 
Ejemplo n.º 7
0
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	();
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
0
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;
}
Ejemplo n.º 10
0
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);
		}
	}
}
Ejemplo n.º 11
0
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;
}
Ejemplo n.º 12
0
//-----------------------------------------------------------------------------
// 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();
}
Ejemplo n.º 13
0
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	();
}
Ejemplo n.º 14
0
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();
    }
}
Ejemplo n.º 15
0
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;
}
Ejemplo n.º 16
0
//! 显示数据
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;
		}
	}
}
Ejemplo n.º 17
0
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
}
Ejemplo n.º 18
0
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");
    }
}
Ejemplo n.º 21
0
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);
				}
			}
		}
	}
}