JAVC++ 2022-08-30 13:37 采纳率: 0%
浏览 46

编辑器内一切正常,打包后出现射线检测不到物体模型的问题

大家好,目前使用UE5.0进行一个项目,在完成射线检测的过程中,打包后发现与射线相交的物体识别不到(在编辑器中运行是没有问题的)。请问各位是出了什么问题
理想状态下,射线交互的物体是会点击边缘高亮显示

img

代码如图所示,在运行中代码会生成一个用于与射线相交的模型

#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;
}


头文件如下:

// 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;


};


  • 写回答

2条回答 默认 最新

  • 飞翔的驴儿 2022-08-30 15:06
    关注

    代码看着费劲,我提个我之前碰到的思路,看下3方库的版本是否一致

    评论

报告相同问题?

问题事件

  • 创建了问题 8月30日

悬赏问题

  • ¥15 flink cdc无法实时同步mysql数据
  • ¥100 有人会搭建GPT-J-6B框架吗?有偿
  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名