zoukankan      html  css  js  c++  java
  • UE4读取脑电波MindWave插件(展示如何使用第三方库制作UE4插件)

    MyEEGPlugin.uplugin

    {
        "FileVersion": 3,
        "Version": 1,
        "VersionName": "1.0",
        "FriendlyName": "MyEEGPlugin",
        "Description": "",
        "Category": "Other",
        "CreatedBy": "",
        "CreatedByURL": "",
        "DocsURL": "",
        "MarketplaceURL": "",
        "SupportURL": "",
        "CanContainContent": true,
        "IsBetaVersion": false,
        "Installed": false,
        "Modules": [
            {
                "Name": "MyEEGPlugin",
                "Type": "Runtime",
                "LoadingPhase": "Default"
            }
        ]
    }

    MyEEGPlugin.Build.cs

    // Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
    
    using UnrealBuildTool;
    using System.IO;
    
    public class MyEEGPlugin : ModuleRules
    {
        public MyEEGPlugin(TargetInfo Target)
        {
            
            PublicIncludePaths.AddRange(
                new string[] {
                    "MyEEGPlugin/Public"
                    // ... add public include paths required here ...
                }
                );
                    
            
            PrivateIncludePaths.AddRange(
                new string[] {
                    "MyEEGPlugin/Private",
                    // ... add other private include paths required here ...
                }
                );
                
            
            PublicDependencyModuleNames.AddRange(
                new string[]
                {
                    "Core", "CoreUObject", "Engine", "InputCore", "Projects"
                    // ... add other public dependencies that you statically link with here ...
                }
                );
                
            
            PrivateDependencyModuleNames.AddRange(
                new string[]
                {
                    // ... add private dependencies that you statically link with here ...    
                }
                );
            
            
            DynamicallyLoadedModuleNames.AddRange(
                new string[]
                {
                    // ... add any modules that your module loads dynamically here ...
                }
                );
    
            LoadThinkGearLib(Target);//添加第三方库
            //LoadAlgoSdkDll(Target);//添加第三方库
        }
    
        private string ThirdPartyPath
        {
            get
            {
                return Path.GetFullPath(Path.Combine(ModuleDirectory, "../ThirdParty/"));
            }
        }
    
        public void LoadThinkGearLib(TargetInfo Target)
        {
            if ((Target.Platform == UnrealTargetPlatform.Win64) || (Target.Platform == UnrealTargetPlatform.Win32))
            {
                string PlatformString = (Target.Platform == UnrealTargetPlatform.Win64) ? "64" : "";
                string LibrariesPath = Path.Combine(ThirdPartyPath, "ThinkGear", "lib");
                
                //test your path
                System.Console.WriteLine("... LibrariesPath -> " + LibrariesPath);
    
                PublicIncludePaths.Add(Path.Combine(ThirdPartyPath, "ThinkGear", "include"));
                PublicAdditionalLibraries.Add(Path.Combine(LibrariesPath, "thinkgear" + PlatformString + ".lib"));
            }
    
            //Definitions.Add(string.Format("MY_DEFINE={0}", 0));
        }
    
        public void LoadAlgoSdkDll(TargetInfo Target)
        {
            if ((Target.Platform == UnrealTargetPlatform.Win64) || (Target.Platform == UnrealTargetPlatform.Win32))
            {
                string PlatformString = (Target.Platform == UnrealTargetPlatform.Win64) ? "64" : "";
                string DllPath = Path.Combine(ThirdPartyPath, "bin", "AlgoSdkDll" + PlatformString + ".dll");
    
                PublicIncludePaths.Add(Path.Combine(ThirdPartyPath, "EEGAlgoSDK", "include"));
                PublicDelayLoadDLLs.Add(DllPath);
                //RuntimeDependencies.Add(new RuntimeDependency(DllPath));
            }
        }
    
    }

    MyEEGPlugin.h

    // Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
    
    #pragma once
    
    #include "ModuleManager.h"
    
    class FMyEEGPluginModule : public IModuleInterface
    {
    public:
    
        /** IModuleInterface implementation */
        virtual void StartupModule() override;
        virtual void ShutdownModule() override;
    
    private:
        /** Handle to the test dll we will load */
        void*    ExampleLibraryHandle;
    };

    MyEEGPlugin.cpp

    // Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
    
    #include "MyEEGPlugin.h"
    #include "Core.h"
    #include "ModuleManager.h"
    #include "IPluginManager.h"
    //#include "ExampleLibrary.h"
    
    #define LOCTEXT_NAMESPACE "FMyEEGPluginModule"
    
    void FMyEEGPluginModule::StartupModule()
    {
        // This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
    
        // Get the base directory of this plugin
        FString BaseDir = IPluginManager::Get().FindPlugin("MyEEGPlugin")->GetBaseDir();
    
        // Add on the relative location of the third party dll and load it
        FString LibraryPath;
    #if PLATFORM_WINDOWS
        LibraryPath = FPaths::Combine(*BaseDir, TEXT("Binaries/ThirdParty/MyEEGPluginLibrary/Win64/ExampleLibrary.dll"));
    #elif PLATFORM_MAC
        LibraryPath = FPaths::Combine(*BaseDir, TEXT("Source/ThirdParty/MyEEGPluginLibrary/Mac/Release/libExampleLibrary.dylib"));
    #endif // PLATFORM_WINDOWS
    
        ExampleLibraryHandle = !LibraryPath.IsEmpty() ? FPlatformProcess::GetDllHandle(*LibraryPath) : nullptr;
    
        if (ExampleLibraryHandle)
        {
            // Call the test function in the third party library that opens a message box
            //ExampleLibraryFunction();
        }
        else
        {
            //FMessageDialog::Open(EAppMsgType::Ok, LOCTEXT("ThirdPartyLibraryError", "Failed to load example third party library"));
        }
    }
    
    void FMyEEGPluginModule::ShutdownModule()
    {
        // This function may be called during shutdown to clean up your module.  For modules that support dynamic reloading,
        // we call this function before unloading the module.
    
        // Free the dll handle
        FPlatformProcess::FreeDllHandle(ExampleLibraryHandle);
        ExampleLibraryHandle = nullptr;
    }
    
    #undef LOCTEXT_NAMESPACE
        
    IMPLEMENT_MODULE(FMyEEGPluginModule, MyEEGPlugin)

    MyEEGReceiver.h

    // Fill out your copyright notice in the Description page of Project Settings.
    
    #pragma once
    #include "Engine.h"
    #include "GameFramework/Actor.h"
    #include "MyEEGReceiver.generated.h"
    
    UCLASS()
    class AMyEEGReceiver : public AActor
    {
        GENERATED_BODY()
        
    public:    
        // Sets default values for this actor's properties
        AMyEEGReceiver();
    
    protected:
        // Called when the game starts or when spawned
        virtual void BeginPlay() override;
        int rawDataIndex;
        int lerpDataIndex;
        float totalAngle;
    
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "EEG")
        float v;
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "EEG")
        float s;
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "EEG")
        float a;
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "EEG")
        TArray<float> rawAttentions;
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "EEG")
        TArray<float> rawMeditations;
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "EEG")
        TArray<float> lerpAttentions;
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "EEG")
        TArray<float> lerpMeditations;
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "EEG")
        float attention1;
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "EEG")
        float attention2;
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "EEG")
        float meditation1;
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "EEG")
        float meditation2;
    public:    
        // Called every frame
        virtual void Tick(float DeltaTime) override;
    
        /** Called whenever this actor is being removed from a level */
        virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
    
        
        UFUNCTION(BlueprintImplementableEvent, Category = "EEG")
        void BPEvent_GetNewAttention(float newAttention);
        
        UFUNCTION(BlueprintCallable, Category = "EEG")
        void IndexFunc();
    
        UFUNCTION(BlueprintCallable, Category = "EEG")
        void ComputeNewPos(float factor, UStaticMeshComponent* cube, float DeltaTime, float scaleFactorAtten=1, float scaleFactorMedi = 1, bool debug=false);
    
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "EEG")
        int32 LatestMeditation;        //最新放松度
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "EEG")
        int32 LatestAttention;        //最新专注度
    
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "EEG")
        bool ShowOnScreenDebugMessages;
        
        FORCEINLINE void ScreenMsg(const FString& Msg)
        {
            if (!ShowOnScreenDebugMessages) return;
            GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, *Msg);
        }
        FORCEINLINE void ScreenMsg(const FString& Msg, const int32 Value)
        {
            if (!ShowOnScreenDebugMessages) return;
            GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("%s %d"), *Msg, Value));
        }
    };

    MyEEGReceiver.cpp

    // Fill out your copyright notice in the Description page of Project Settings.
    
    #include "MyEEGPlugin.h"
    #include "MyEEGReceiver.h"
    #include "thinkgear.h"
    
    #define NUM 3
    // Sets default values
    AMyEEGReceiver::AMyEEGReceiver()
    {
         // 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;
    
        ShowOnScreenDebugMessages = true;
        v = 0; a = 1; s = 0;
        rawDataIndex = 0;
        lerpDataIndex = 0;
        rawAttentions.Init(0, NUM);
        rawMeditations.Init(0, NUM);
        totalAngle = 0;
    }
    
    long raw_data_count = 0;
    short *raw_data = NULL;
    bool bRunning = false;
    bool bInited = false;
    char *comPortName = NULL;
    int   dllVersion = 0;
    int   connectionId = -1;
    int   packetsRead = 0;
    int   errCode = 0;
    bool bConnectedHeadset = false;
    
    
    // Called when the game starts or when spawned
    void AMyEEGReceiver::BeginPlay()
    {
        Super::BeginPlay();
    
        /* Print driver version number */
        dllVersion = TG_GetVersion();
        ScreenMsg("ThinkGear DLL version:",dllVersion);
        //GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("ThinkGear DLL version: %d
    "), dllVersion));
        /* Get a connection ID handle to ThinkGear */
        connectionId = TG_GetNewConnectionId();
        if (connectionId < 0) {
            ScreenMsg("Failed to new connection ID");
        }
        else {
            /* Attempt to connect the connection ID handle to serial port "COM5" */
            /* NOTE: On Windows, COM10 and higher must be preceded by \.\, as in
            *       "\\.\COM12" (must escape backslashes in strings).  COM9
            *       and lower do not require the \.\, but are allowed to include
            *       them.  On Mac OS X, COM ports are named like
            *       "/dev/tty.MindSet-DevB-1".
            */
            comPortName = "\\.\COM6";
            errCode = TG_Connect(connectionId,
                comPortName,
                TG_BAUD_57600,
                TG_STREAM_PACKETS);
            if (errCode < 0) 
            {
                ScreenMsg("TG_Connect() failed", errCode);
            }
            else
            {
                ScreenMsg("TG_Connect OK",connectionId);
            }
        }
    
    }
    
    // Called every frame
    void AMyEEGReceiver::Tick(float DeltaTime)
    {
        Super::Tick(DeltaTime);
    
        v = v + a*DeltaTime;
        s += v*DeltaTime;
        /* Read all currently available Packets, one at a time... */
        do {
            /* Read a single Packet from the connection */
            packetsRead = TG_ReadPackets(connectionId, 1);
            
            /* If TG_ReadPackets() was able to read a Packet of data... */
            if (packetsRead == 1) {
                //ScreenMsg("TG_ReadPackets");
                /* If the Packet containted a new raw wave value... */
                if (TG_GetValueStatus(connectionId, TG_DATA_RAW) != 0) {
                    int rawData = (int)TG_GetValue(connectionId, TG_DATA_RAW);
                    //ScreenMsg("TG_DATA_RAW",rawData);
                } /* end "If Packet contained a raw wave value..." */
    
                if (TG_GetValueStatus(connectionId, TG_DATA_POOR_SIGNAL) != 0) {
                    int ps=TG_GetValue(connectionId, TG_DATA_POOR_SIGNAL);
                    //ScreenMsg("TG_DATA_POOR_SIGNAL",ps);
                }
    
                if (TG_GetValueStatus(connectionId, TG_DATA_MEDITATION) != 0) {
                    float medi = TG_GetValue(connectionId, TG_DATA_MEDITATION);
                    LatestMeditation = (int32)medi;
                    //ScreenMsg("TG_DATA_MEDITATION", LatestMeditation);
                    rawMeditations[rawDataIndex] = medi;
                    float total = 0;
                    for (int i = 0; i < NUM; i++)
                        total += rawMeditations[i];
                    float avg_medi = total / NUM;
                    lerpMeditations.Add(avg_medi);
                }
    
                if (TG_GetValueStatus(connectionId, TG_DATA_ATTENTION) != 0) {
                    float atten = TG_GetValue(connectionId, TG_DATA_ATTENTION);
                    LatestAttention = (int32)atten;
                    rawAttentions[rawDataIndex] = atten;
                    float total = 0;
                    for (int i = 0; i < NUM; i++)
                        total += rawAttentions[i];
                    float avg_atten = total / NUM;
                    lerpAttentions.Add(avg_atten);
    
                    rawDataIndex++;
                    if (rawDataIndex == NUM)
                    {
                        rawDataIndex = 0;
                    }
    
                    ScreenMsg("avg_atten", avg_atten);
                    //BPEvent_GetNewAttention(TG_GetValue(connectionId, TG_DATA_ATTENTION));
                    //float atten=TG_GetValue(connectionId, TG_DATA_ATTENTION);
                    //float delta = atten - s;
                    //a = delta;
                    ScreenMsg("TG_DATA_ATTENTION", LatestAttention);
                    //ScreenMsg("delta", delta);
                    //ScreenMsg("s", s);
                }
    
            } /* end "If TG_ReadPackets() was able to read a Packet..." */
    
        } while (packetsRead > 0); /* Keep looping until all Packets read */
    }
    
    void AMyEEGReceiver::EndPlay(const EEndPlayReason::Type EndPlayReason)
    {
        Super::EndPlay(EndPlayReason);
    
        /* Clean up */
        TG_FreeConnection(connectionId);
    }
    
    void AMyEEGReceiver::IndexFunc()
    {
        int lerpNum = lerpAttentions.Num();
        if (lerpNum ==0)
            return;
        int idx1 = lerpDataIndex - 1;
        int idx2 = lerpDataIndex;
        idx1 = FMath::Max(idx1,0);
        idx2 = FMath::Min(idx2, lerpNum-1);
        attention1 = lerpAttentions[idx1];
        attention2 = lerpAttentions[idx2];
        meditation1 = lerpMeditations[idx1];
        meditation2 = lerpMeditations[idx2];
        if (lerpDataIndex < lerpNum-1)
        {
            lerpDataIndex++;
        }
    }
    
    void AMyEEGReceiver::ComputeNewPos(float factor, UStaticMeshComponent* cube, float DeltaTime,
        float scaleFactorAtten/*=1*/, float scaleFactorMedi/* = 1*/, bool debug/* = false*/)
    {
        float tmpAtten = FMath::Lerp(attention1, attention2, factor);
        float tmpMedit = FMath::Lerp(meditation1, meditation2, factor);
        static float testTime = 0;
        if (debug)
        {
            tmpMedit = 50 + sin(testTime) * 50;
            tmpAtten = 50 + sin(testTime) * 50; testTime += DeltaTime;
        }
        float s0 = tmpMedit*DeltaTime*scaleFactorMedi;
        FVector oldPos = cube->GetComponentLocation();
        float angle = FMath::Atan(s0 / (oldPos.Size()));
        FVector normalVec = oldPos.GetSafeNormal();
        FVector newPos = normalVec*(10000 + tmpAtten*scaleFactorAtten);
        cube->SetWorldLocation(newPos.RotateAngleAxis(FMath::RadiansToDegrees(angle),FVector(0,1,0)));
        FRotator Rotator = FRotator::ZeroRotator;
        totalAngle += FMath::RadiansToDegrees(angle);
        Rotator.Add(-totalAngle, 0, 0);
        if (totalAngle >= 360)
        {
            totalAngle = 0;
        }
        cube->SetWorldRotation(Rotator);
        UTextRenderComponent* text = dynamic_cast<UTextRenderComponent*>(cube->GetChildComponent(0));
        if (text)
        {
            FString t1 = FString::FromInt(tmpAtten);
            FString t2 = FString::FromInt(tmpMedit);
            FString t3 = FString::FromInt(totalAngle);
            FString tmp(", ");
            tmp = t1 + tmp + t2;
            text->SetText(FText::FromString(tmp));
        }
    }
  • 相关阅读:
    HDU 5835 Danganronpa 贪心
    HDU 5842 Lweb and String 水题
    HDU 5832 A water problem 水题
    Codeforces Beta Round #14 (Div. 2) A. Letter 水题
    Western Subregional of NEERC, Minsk, Wednesday, November 4, 2015 Problem K. UTF-8 Decoder 模拟题
    Western Subregional of NEERC, Minsk, Wednesday, November 4, 2015 Problem I. Alien Rectangles 数学
    Western Subregional of NEERC, Minsk, Wednesday, November 4, 2015 Problem H. Parallel Worlds 计算几何
    Western Subregional of NEERC, Minsk, Wednesday, November 4, 2015 Problem F. Turning Grille 暴力
    Western Subregional of NEERC, Minsk, Wednesday, November 4, 2015 Problem C. Cargo Transportation 暴力
    Western Subregional of NEERC, Minsk, Wednesday, November 4, 2015 Problem G. k-palindrome dp
  • 原文地址:https://www.cnblogs.com/coolbear/p/7160262.html
Copyright © 2011-2022 走看看