Hello Everyone, there is a project using UE5.0, in the process of completing the X-ray detection, after the packaging of objects with the X-ray intersection can not be recognized (in the editor is no problem) . What seems to be the problem??
Ideally, ray-interacting objects would be highlighted by clicking on the edges
and the following is my Code:
cpp_code
#include "MyActorFromOgl.h"
// Sets default values
AMyActorFromOgl::AMyActorFromOgl()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
SuperMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("OGL Mesh"),false);
//设定其为根组件:
SetRootComponent(SuperMesh);
//static ConstructorHelpers::FObjectFinder<UMaterial> plane_material(TEXT("/Game/Materials/MyMaterial.MyMaterial"));
//SuperMesh->SetMaterial(0, plane_material.Object);
//LoadOGL("E:/MyProjects/Unreal/TestLoadFile/Saved/OGL/118442645.ogl");
}
AMyActorFromOgl::AMyActorFromOgl(FString oglpath, UMaterial* _material)
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
SuperMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("OGL Mesh"), false);
//设定其为根组件:
SetRootComponent(SuperMesh);
//static ConstructorHelpers::FObjectFinder<UMaterial> plane_material(TEXT("/Game/Materials/MyMaterial.MyMaterial"));
SuperMesh->SetMaterial(0, _material);
//LoadOGL("E:/MyProjects/Unreal/TestLoadFile/Saved/OGL/118442645.ogl");
}
// Called when the game starts or when spawned
void AMyActorFromOgl::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void AMyActorFromOgl::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
int32 AMyActorFromOgl::AppendOGLVertices(FMeshDescriptionBuilder& builder, uint8* buffer, int32& vertexCount)
{
//int32* intBuffer = reinterpret_cast<int32*>(buffer);
//int32 version = *(intBuffer + 0), byteOffset = sizeof(int32) * 2;
//int32 normalCount = 0, uvCount = 0;
//vertexCount = *(intBuffer + 1) / 3;
int32* intBuffer = (int32*)(buffer);
int32 version = intBuffer[0], byteOffset = sizeof(int32) * 2;
int32 normalCount = 0, uvCount = 0;
vertexCount =intBuffer[1] / 3;
FVector3f* vertices = reinterpret_cast<FVector3f*>(buffer + byteOffset);
byteOffset += sizeof(FVector3f) * vertexCount;
intBuffer = reinterpret_cast<int32*>(buffer + byteOffset);
normalCount = *(intBuffer + 0) / 3;
byteOffset += sizeof(int32);
FVector3f* normals = reinterpret_cast<FVector3f*>(buffer + byteOffset);
byteOffset += sizeof(FVector3f) * normalCount;
intBuffer = reinterpret_cast<int32*>(buffer + byteOffset);
uvCount = *(intBuffer + 0) / 2;
byteOffset += sizeof(int32);
FVector2f* uvs = reinterpret_cast<FVector2f*>(buffer + byteOffset);
byteOffset += sizeof(FVector2f) * uvCount;
FVector2D uv(0.0);
FVector vertex(0.0), normal(0.0);
for (int i = 0; i < vertexCount; i++)
{
FVector3f& vertexF = *(vertices + i);
FVector3f& normalF = *(normals + i);
FVector2f& uvF = *(uvs + i);
vertex.X = vertexF.X; vertex.Y = vertexF.Y; vertex.Z = vertexF.Z;
normal.X = normalF.X; normal.Y = normalF.Y; normal.Z = normalF.Z;
uv.X = uvF.X; uv.Y = uvF.Y;
FVertexID vertexID = builder.AppendVertex(vertex);
FVertexInstanceID instanceID = builder.AppendInstance(vertexID);
builder.SetInstanceNormal(instanceID, normal);
builder.SetInstanceUV(instanceID, uv);
}
return byteOffset;
}
int32 AMyActorFromOgl::AppendOGLTriangles(FMeshDescriptionBuilder& builder, FMeshDescription& description, uint8* buffer, int32 byteOffset, int32& triangleCount)
{
int32* intBuffer = reinterpret_cast<int32*>(buffer + byteOffset);
int32 indexLength = *(intBuffer + 1);
bool useShort = *(intBuffer + 0) == 0;
byteOffset += sizeof(int32) * 2;
int32* indices = reinterpret_cast<int32*>(buffer + byteOffset);
byteOffset += useShort ? sizeof(uint16) * indexLength : sizeof(int32) * indexLength;
byteOffset += useShort && (indexLength & 0x01) == 0x01 ? sizeof(uint16) : 0;
intBuffer = reinterpret_cast<int32*>(buffer + byteOffset);
byteOffset += sizeof(int32);
int32 subMeshCount = *(intBuffer + 0);
int32* subMeshes = reinterpret_cast<int32*>(buffer + byteOffset);
if (useShort)
{
uint16* shortIndices = reinterpret_cast<uint16*>(indices);
for (int i = 0; i < subMeshCount; i++)
{
int32 baseIndex = (i << 1) + i; // i * 3
int32 indexStart = *(subMeshes + baseIndex + 0);
int32 indexCount = *(subMeshes + baseIndex + 1);
int32 materialId = *(subMeshes + baseIndex + 2);
FPolygonGroupID groupID = builder.AppendPolygonGroup();
int indexEnd = indexStart + indexCount;
for (int j = indexStart; j < indexEnd; j += 3)
{
FVertexInstanceID index0 = static_cast<FVertexInstanceID>(*(shortIndices + j + 0));
FVertexInstanceID index1 = static_cast<FVertexInstanceID>(*(shortIndices + j + 2));
FVertexInstanceID index2 = static_cast<FVertexInstanceID>(*(shortIndices + j + 1));
FTriangleID triangleID = builder.AppendTriangle(index0, index1, index2, groupID);
triangleCount++;
}
}
}
else
{
for (int i = 0; i < subMeshCount; i++)
{
int32 baseIndex = (i << 1) + i;
int32 indexStart = *(subMeshes + baseIndex + 0);
int32 indexCount = *(subMeshes + baseIndex + 1);
int32 materialId = *(subMeshes + baseIndex + 2);
FPolygonGroupID groupID = builder.AppendPolygonGroup();
int indexEnd = indexStart + indexCount;
for (int j = indexStart; j < indexEnd; j += 3)
{
FVertexInstanceID index0 = static_cast<FVertexInstanceID>(*(indices + j + 0));
FVertexInstanceID index1 = static_cast<FVertexInstanceID>(*(indices + j + 2));
FVertexInstanceID index2 = static_cast<FVertexInstanceID>(*(indices + j + 1));
FTriangleID triangleID = builder.AppendTriangle(index0, index1, index2, groupID);
triangleCount++;
}
}
}
return subMeshCount;
}
int AMyActorFromOgl::FillStaticMeshWithOGL(uint8* buffer, int geometryId)
{
if (buffer == nullptr)
{
return 0;
}
// MeshDescription ��������StaticMesh����Ϣ���������Σ�UV������ ��
FMeshDescription meshDescription;
FStaticMeshAttributes attributes(meshDescription);
attributes.Register();
FMeshDescriptionBuilder descriptionBuilder;
descriptionBuilder.SetMeshDescription(&meshDescription);
descriptionBuilder.EnablePolyGroups();
descriptionBuilder.SetNumUVLayers(1);
int vertexCount = 0;
int triangleCount = 0;
int byteOffset = AppendOGLVertices(descriptionBuilder, buffer, vertexCount);
int subMeshCount = AppendOGLTriangles(descriptionBuilder, meshDescription, buffer, byteOffset, triangleCount);
if (geometryId == 893294 || geometryId == 893348)
{
UE_LOG(LogTemp, Log, TEXT("GeoemetryId: %d"), geometryId);
UE_LOG(LogTemp, Log, TEXT("vertexCount: %d"), vertexCount);
UE_LOG(LogTemp, Log, TEXT("triangleCount: %d"), triangleCount);
}
//设定模型名字
FString MeshName = FString::Printf(TEXT("%d"), geometryId);
//设定包的路径
FString PackageName = "/Game/Geometry/" + MeshName;
//创建包
UPackage* MeshPackage = CreatePackage(nullptr, *PackageName);
staticMesh = NewObject<UStaticMesh>( MeshPackage, FName(*MeshName), RF_Public | RF_Standalone);
//TArray< FText > BuildErrors;
//staticMesh->Build(true, &BuildErrors);
staticMesh->GetStaticMaterials().Add(FStaticMaterial());
//staticMesh->AddMaterial(_material);
UStaticMesh::FBuildMeshDescriptionsParams params;
params.bBuildSimpleCollision = true;
params.bFastBuild = true;
TArray<const FMeshDescription*> meshDescriptionPtrs;
meshDescriptionPtrs.Emplace(&meshDescription);
if (staticMesh->BuildFromMeshDescriptions(meshDescriptionPtrs, params)) {
SuperMesh->SetStaticMesh(staticMesh);
}
return subMeshCount;
}
bool AMyActorFromOgl::LoadOGL(FString _path, TArray <UMaterialInterface*> _materials, int geometryId)
{
//Load the Compressed data array
TArray<uint8> Buffer;
bool result = false;
result = UBaseFilesDownloader::LoadFileToArray(Buffer, *_path);
if (result) {
FillStaticMeshWithOGL(&Buffer[0], geometryId);
for (size_t i = 0; i < _materials.Num(); i++)
{
SuperMesh->SetMaterial(i, _materials[i]);
}
}
return result;
}
> Blockquote
and there is my cpp_head file
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include <Engine/StaticMesh.h>
#include <MeshDescription.h>
#include <MeshConversion/public/MeshDescriptionBuilder.h>
#include <StaticMeshAttributes.h>
#include "BaseFilesDownloader.h"
#include "MyActorFromOgl.generated.h"
UCLASS()
class PIXELS_NANITE_API AMyActorFromOgl : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AMyActorFromOgl();
AMyActorFromOgl(FString oglpath,UMaterial* _material);
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
int FillStaticMeshWithOGL(uint8* buffer, int geometryId);
int32 AppendOGLVertices(FMeshDescriptionBuilder& builder, uint8* buffer, int32& vertexCount);
int32 AppendOGLTriangles(FMeshDescriptionBuilder& builder, FMeshDescription& description, uint8* buffer, int32 byteOffset, int32& triangleCount);
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
UFUNCTION(BlueprintCallable)
// bool LoadOGL(FString _path, UMaterialInterface* _material);
bool LoadOGL(FString _path, TArray<UMaterialInterface*> _materials, int geometryId);
//UFUNCTION(BlueprintCallable)
// bool LoadOGL(TArray<uint8> &Buffer, FString _path);
UPROPERTY(EditAnywhere)
UStaticMeshComponent* SuperMesh;
UPROPERTY(EditAnywhere)
UStaticMesh* staticMesh;
};