Support for looping patterns with rotation

- Steam jets can be directional now
- Added couple of missing haptics files
- Adjusted Pistol/Shotgun and Chainsaw patterns
This commit is contained in:
Simon 2021-03-25 22:25:46 +00:00
parent e8e2d76a01
commit 253d55387d
8 changed files with 168 additions and 37 deletions

View file

@ -956,6 +956,7 @@ void Doom3Quest_Vibrate(int channel, float low, float high)
}
void jni_haptic_event(const char* event, int position, int flags, int intensity, float angle, float yHeight);
void jni_haptic_updateevent(const char* event, int intensity, float angle);
void jni_haptic_stopevent(const char* event);
void jni_haptic_beginframe();
void jni_haptic_endframe();
@ -967,6 +968,11 @@ void Doom3Quest_HapticEvent(const char* event, int position, int flags, int inte
jni_haptic_event(event, position, flags, intensity, angle, yHeight);
}
void Doom3Quest_HapticUpdateEvent(const char* event, int intensity, float angle )
{
jni_haptic_updateevent(event, intensity, angle);
}
void Doom3Quest_HapticBeginFrame()
{
jni_haptic_beginframe();
@ -1959,6 +1965,7 @@ Activity lifecycle
jmethodID android_shutdown;
jmethodID android_haptic_event;
jmethodID android_haptic_updateevent;
jmethodID android_haptic_stopevent;
jmethodID android_haptic_beginframe;
jmethodID android_haptic_endframe;
@ -1993,6 +2000,20 @@ void jni_haptic_event(const char* event, int position, int flags, int intensity,
return (*env)->CallVoidMethod(env, jniCallbackObj, android_haptic_event, StringArg1, position, flags, intensity, angle, yHeight);
}
void jni_haptic_updateevent(const char* event, int intensity, float angle)
{
JNIEnv *env;
jobject tmp;
if (((*jVM)->GetEnv(jVM, (void**) &env, JNI_VERSION_1_4))<0)
{
(*jVM)->AttachCurrentThread(jVM,&env, NULL);
}
jstring StringArg1 = (*env)->NewStringUTF(env, event);
return (*env)->CallVoidMethod(env, jniCallbackObj, android_haptic_updateevent, StringArg1, intensity, angle);
}
void jni_haptic_stopevent(const char* event)
{
ALOGV("Calling: jni_haptic_stopevent");
@ -2132,6 +2153,7 @@ JNIEXPORT void JNICALL Java_com_drbeef_doom3quest_GLES3JNILib_onStart( JNIEnv *
android_shutdown = (*env)->GetMethodID(env,callbackClass,"shutdown","()V");
android_haptic_event = (*env)->GetMethodID(env, callbackClass, "haptic_event", "(Ljava/lang/String;IIIFF)V");
android_haptic_updateevent = (*env)->GetMethodID(env, callbackClass, "haptic_updateevent", "(Ljava/lang/String;IF)V");
android_haptic_stopevent = (*env)->GetMethodID(env, callbackClass, "haptic_stopevent", "(Ljava/lang/String;)V");
android_haptic_beginframe = (*env)->GetMethodID(env, callbackClass, "haptic_beginframe", "()V");
android_haptic_endframe = (*env)->GetMethodID(env, callbackClass, "haptic_endframe", "()V");

View file

@ -1631,7 +1631,7 @@ bool idEntity::StartSoundShader( const idSoundShader *shader, const s_channelTyp
float distance = direction.Length();
if (distance <= 150.0F) {
bool repeat = (shader->GetParms()->soundShaderFlags & SSF_LOOPING) != 0;
bool looping = (shader->GetParms()->soundShaderFlags & SSF_LOOPING) != 0;
direction.Normalize();
idVec3 bodyOrigin = vec3_zero;
@ -1639,16 +1639,15 @@ bool idEntity::StartSoundShader( const idSoundShader *shader, const s_channelTyp
player->GetViewPos( bodyOrigin, bodyAxis );
idAngles bodyAng = bodyAxis.ToAngles();
/* float pitch = direction.ToPitch();
if (pitch > 180)
pitch -= 360;
float yHeight = idMath::ClampFloat(-0.5f, 0.45f, -pitch / 90.0f);*/
idAngles directionYaw(0, 180 + (direction.ToYaw() - bodyAng.yaw), 0);
directionYaw.Normalize360();
//Pass sound on in case it can trigger a haptic event (like doors)
float intensity = 40 + Min<float>((int)(150.0f - distance), 80);
common->HapticEvent(shader->GetName(), 4, repeat ? 1 : 0, intensity, directionYaw.yaw, 0);
float intensity = looping ? (100.0f - distance) :
40 + Min<float>((int)(150.0f - distance), 80);
common->HapticEvent(shader->GetName(), 4, looping ? 1 : 0, intensity,
directionYaw.yaw, 0);
}
}

View file

@ -5741,22 +5741,29 @@ void idPlayerHand::NextWeapon( int dir )
vr_weaponHand.SetInteger( 1 - whichHand );
}
if (currentWeapon == WEAPON_CHAINSAW)
{
//Stop all chainsaw haptics immediately
common->HapticStopEvent("chainsaw_idle");
common->HapticStopEvent("chainsaw_fire");
}
idealWeapon = w;
weaponSwitchTime = gameLocal.time + WEAPON_SWITCH_DELAY;
owner->UpdateHudWeapon( whichHand );
if( vr_debugHands.GetBool() )
common->Printf( "Changing weapon\n" );
common->HapticEvent("weapon_switch", 0, 0, 100, 0, 0);
if (idealWeapon == WEAPON_CHAINSAW)
{
//Start chainsaw idling haptic immediately
common->HapticEvent("chainsaw_idle", vr_weaponHand.GetInteger() ? 1 : 2, 1, 100, 0, 0);
}
else
{
common->HapticStopEvent("chainsaw_idle");
}
else
{
common->HapticEvent("weapon_switch", 0, 0, 100, 0, 0);
}
}
if( vr_debugHands.GetBool() )

View file

@ -26,6 +26,7 @@ If you have questions concerning this license or the applicable additional terms
===========================================================================
*/
#include <d3es-multithread-master/neo/framework/Game.h>
#include "sys/platform.h"
#include "framework/FileSystem.h"
#include "framework/Session.h"
@ -33,6 +34,9 @@ If you have questions concerning this license or the applicable additional terms
#include "sound/snd_local.h"
//Haptic Stuff
extern "C" void Doom3Quest_HapticUpdateEvent(const char* event, int intensity, float angle );
/*
==================
idSoundWorldLocal::Init
@ -1589,6 +1593,8 @@ void idSoundWorldLocal::CalcEars( int numSpeakers, idVec3 spatializedOrigin, idV
}
}
extern idGame * game;
/*
===============
idSoundWorldLocal::AddChannelContribution
@ -1755,6 +1761,27 @@ void idSoundWorldLocal::AddChannelContribution( idSoundEmitterLocal *sound, idSo
float inputSamples[MIXBUFFER_SAMPLES*2+16];
float *alignedInputSamples = (float *) ( ( ( (intptr_t)inputSamples ) + 15 ) & ~15 );
if (cvarSystem->GetCVarBool("vr_bhaptics") &&
looping &&
game != NULL)
{
idVec3 direction = (listenerPos / DOOM_TO_METERS) - sound->origin;
float distance = direction.Length();
if (distance <= 100.0F) {
direction.Normalize();
idAngles bodyAng = listenerAxis.ToAngles();
idAngles directionYaw(0, 180 + (direction.ToYaw() - bodyAng.yaw), 0);
directionYaw.Normalize360();
int intensity = 100 - distance;
Doom3Quest_HapticUpdateEvent(shader->GetName(), intensity, directionYaw.yaw);
} else{
Doom3Quest_HapticUpdateEvent(shader->GetName(), 0, 0);
}
}
//
// allocate and initialize hardware source
//

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
{"project":{"createdAt":1614063863216,"description":"","id":"-MUCh-OyqGJ1QiTCDLOU","layout":{"layouts":{"VestBack":[{"index":0,"x":0,"y":0},{"index":1,"x":0.333,"y":0},{"index":2,"x":0.667,"y":0},{"index":3,"x":1,"y":0},{"index":4,"x":0,"y":0.25},{"index":5,"x":0.333,"y":0.25},{"index":6,"x":0.667,"y":0.25},{"index":7,"x":1,"y":0.25},{"index":8,"x":0,"y":0.5},{"index":9,"x":0.333,"y":0.5},{"index":10,"x":0.667,"y":0.5},{"index":11,"x":1,"y":0.5},{"index":12,"x":0,"y":0.75},{"index":13,"x":0.333,"y":0.75},{"index":14,"x":0.667,"y":0.75},{"index":15,"x":1,"y":0.75},{"index":16,"x":0,"y":1},{"index":17,"x":0.333,"y":1},{"index":18,"x":0.667,"y":1},{"index":19,"x":1,"y":1}],"VestFront":[{"index":0,"x":0,"y":0},{"index":1,"x":0.333,"y":0},{"index":2,"x":0.667,"y":0},{"index":3,"x":1,"y":0},{"index":4,"x":0,"y":0.25},{"index":5,"x":0.333,"y":0.25},{"index":6,"x":0.667,"y":0.25},{"index":7,"x":1,"y":0.25},{"index":8,"x":0,"y":0.5},{"index":9,"x":0.333,"y":0.5},{"index":10,"x":0.667,"y":0.5},{"index":11,"x":1,"y":0.5},{"index":12,"x":0,"y":0.75},{"index":13,"x":0.333,"y":0.75},{"index":14,"x":0.667,"y":0.75},{"index":15,"x":1,"y":0.75},{"index":16,"x":0,"y":1},{"index":17,"x":0.333,"y":1},{"index":18,"x":0.667,"y":1},{"index":19,"x":1,"y":1}]},"name":"Tactot","type":"Tactot"},"mediaFileDuration":1,"name":"Body_Reload","tracks":[{"effects":[{"modes":{"VestBack":{"dotMode":{"dotConnected":false,"feedback":[{"endTime":102,"playbackType":"NONE","pointList":[{"index":7,"intensity":0.6}],"startTime":0},{"endTime":204,"playbackType":"FADE_IN","pointList":[{"index":3,"intensity":0.6}],"startTime":102}]},"mode":"DOT_MODE","pathMode":{"feedback":[]}},"VestFront":{"dotMode":{"dotConnected":false,"feedback":[{"endTime":102,"playbackType":"NONE","pointList":[{"index":6,"intensity":0.6},{"index":7,"intensity":0.6}],"startTime":0},{"endTime":204,"playbackType":"FADE_IN","pointList":[{"index":2,"intensity":0.6},{"index":3,"intensity":0.6}],"startTime":102}]},"mode":"DOT_MODE","pathMode":{"feedback":[{"movingPattern":"CONST_SPEED","playbackType":"NONE","visible":true,"pointList":[]}]}}},"name":"Effect 1","offsetTime":204,"startTime":0}],"enable":true},{"enable":true,"effects":[]}],"type":"project","updatedAt":1614063881495},"durationMillis":0,"intervalMillis":20,"size":20}

View file

@ -58,6 +58,11 @@ import static android.system.Os.setenv;
bHaptics.playHaptic(event, position, flags, intensity, angle, yHeight);
}
public void haptic_updateevent(String event, int intensity, float angle) {
bHaptics.updateRepeatingHaptic(event, intensity, angle);
}
public void haptic_stopevent(String event) {
bHaptics.stopHaptic(event);

View file

@ -42,16 +42,37 @@ public class bHaptics {
this.key = key;
this.altKey = altKey;
this.group = group;
this.directional = false;
this.intensity = intensity;
this.duration = duration;
this.rotation = 0;
this.level = 100;
}
public Haptic(Haptic haptic) {
this.type = haptic.type;
this.key = haptic.key;
this.altKey = haptic.altKey;
this.group = haptic.group;
this.directional = haptic.directional;
this.intensity = haptic.intensity;
this.duration = haptic.duration;
this.rotation = 0;
this.level = 100;
}
public final String key;
public final String altKey;
public final String group;
public final float intensity;
public boolean directional; // can be changed for specific repeating patterns
public final float duration;
public final PositionType type;
public final float intensity;
//These two values can be changed over time when playing a looping effect
public float rotation;
public float level;
};
private static final String TAG = "Doom3Quest.bHaptics";
@ -132,14 +153,20 @@ public class bHaptics {
registerFromAsset(context, "bHaptics/Interaction/Arms/Healthstation_L.tact", PositionType.ForearmL, "healstation", "pickup");
registerFromAsset(context, "bHaptics/Interaction/Arms/Healthstation_R.tact", PositionType.ForearmR, "healstation", "pickup");
registerFromAsset(context, "bHaptics/Interaction/Vest/DoorSlide.tact", "doorslide", "door");
registerFromAsset(context, "bHaptics/Interaction/Vest/DoorSlide.tact", PositionType.Vest, "doorslide", "door", 1.0f, 0.5f);
registerFromAsset(context, "bHaptics/Interaction/Vest/Body_Scan.tact", PositionType.Vest, "scan", "environment", 1.0f, 1.15f);
registerFromAsset(context, "bHaptics/Interaction/Vest/Body_Scan.tact", PositionType.Vest, "decontaminate", "environment", 0.5f, 0.75f);
registerFromAsset(context, "bHaptics/Interaction/Vest/Body_Chamber_Up.tact", "liftup", "environment");
registerFromAsset(context, "bHaptics/Interaction/Vest/Body_Chamber_Down.tact", "liftdown", "environment");
registerFromAsset(context, "bHaptics/Interaction/Vest/Body_Machine.tact", "machine", "environment");
registerFromAsset(context, "bHaptics/Interaction/Vest/Spark.tact", "spark", "environment");
registerFromAsset(context, "bHaptics/Interaction/Head/Spark.tact", PositionType.Head, "spark", "environment");
registerFromAsset(context, "bHaptics/Interaction/Head/Spark.tact", PositionType.Head, "spark", "environment", 0.5f, 0.5f);
//Directional based place holder for looping steam pattern
registerFromAsset(context, "bHaptics/Interaction/Vest/Spark.tact", PositionType.Vest, "steam_loop", "environment", 0.5f, 0.25f);
eventToEffectKeyMap.get("steam_loop").elementAt(0).directional = true;
registerFromAsset(context, "bHaptics/Interaction/Vest/Spark.tact", "steam_blast", "environment");
registerFromAsset(context, "bHaptics/Interaction/Vest/Body_PDA_Open.tact", "pda_open", "pda");
registerFromAsset(context, "bHaptics/Interaction/Vest/Body_PDA_Open.tact", "pda_close", "pda");
@ -174,16 +201,16 @@ public class bHaptics {
registerFromAsset(context, "bHaptics/Weapon/Arms/ReloadFinish_Mirror.tact", PositionType.ForearmL, "weapon_reload_finish", "weapon");
//Chainsaw Idle
registerFromAsset(context, "bHaptics/Weapon/Vest/Chainsaw_LV1.tact", PositionType.Right, "chainsaw_idle", "weapon");
registerFromAsset(context, "bHaptics/Weapon/Arms/Chainsaw_LV1.tact", PositionType.ForearmR, "chainsaw_idle", "weapon");
registerFromAsset(context, "bHaptics/Weapon/Vest/Chainsaw_LV1_Mirror.tact", PositionType.Left, "chainsaw_idle", "weapon");
registerFromAsset(context, "bHaptics/Weapon/Arms/Chainsaw_LV1_Mirror.tact", PositionType.ForearmL, "chainsaw_idle", "weapon");
registerFromAsset(context, "bHaptics/Weapon/Vest/Chainsaw_LV2.tact", PositionType.Right, "chainsaw_idle", "weapon");
registerFromAsset(context, "bHaptics/Weapon/Arms/Chainsaw_LV2.tact", PositionType.ForearmR, "chainsaw_idle", "weapon");
registerFromAsset(context, "bHaptics/Weapon/Vest/Chainsaw_LV2_Mirror.tact", PositionType.Left, "chainsaw_idle", "weapon");
registerFromAsset(context, "bHaptics/Weapon/Arms/Chainsaw_LV2_Mirror.tact", PositionType.ForearmL, "chainsaw_idle", "weapon");
//Chainsaw Fire
registerFromAsset(context, "bHaptics/Weapon/Vest/Chainsaw_LV2.tact", PositionType.Right, "chainsaw_fire", "weapon_fire");
registerFromAsset(context, "bHaptics/Weapon/Arms/Chainsaw_LV2.tact", PositionType.ForearmR, "chainsaw_fire", "weapon_fire");
registerFromAsset(context, "bHaptics/Weapon/Vest/Chainsaw_LV2_Mirror.tact", PositionType.Left, "chainsaw_fire", "weapon_fire");
registerFromAsset(context, "bHaptics/Weapon/Arms/Chainsaw_LV2_Mirror.tact", PositionType.ForearmL, "chainsaw_fire", "weapon_fire");
registerFromAsset(context, "bHaptics/Weapon/Vest/Chainsaw_LV1.tact", PositionType.Right, "chainsaw_fire", "weapon_fire");
registerFromAsset(context, "bHaptics/Weapon/Arms/Chainsaw_LV1.tact", PositionType.ForearmR, "chainsaw_fire", "weapon_fire");
registerFromAsset(context, "bHaptics/Weapon/Vest/Chainsaw_LV1_Mirror.tact", PositionType.Left, "chainsaw_fire", "weapon_fire");
registerFromAsset(context, "bHaptics/Weapon/Arms/Chainsaw_LV1_Mirror.tact", PositionType.ForearmL, "chainsaw_fire", "weapon_fire");
//Fist
registerFromAsset(context, "bHaptics/Weapon/Vest/Fist_Mirror.tact", PositionType.Left, "punch", "weapon_fire");
@ -192,16 +219,16 @@ public class bHaptics {
registerFromAsset(context, "bHaptics/Weapon/Arms/Fist.tact", PositionType.ForearmR, "punch", "weapon_fire");
//Pistol
registerFromAsset(context, "bHaptics/Weapon/Vest/Recoil_LV2_Mirror.tact", PositionType.Left, "pistol_fire", "weapon_fire");
registerFromAsset(context, "bHaptics/Weapon/Arms/Recoil_LV2_Mirror.tact", PositionType.ForearmL, "pistol_fire", "weapon_fire");
registerFromAsset(context, "bHaptics/Weapon/Vest/Recoil_LV2.tact", PositionType.Right, "pistol_fire", "weapon_fire");
registerFromAsset(context, "bHaptics/Weapon/Arms/Recoil_LV2.tact", PositionType.ForearmR, "pistol_fire", "weapon_fire");
registerFromAsset(context, "bHaptics/Weapon/Vest/Recoil_LV3_Mirror.tact", PositionType.Left, "pistol_fire", "weapon_fire");
registerFromAsset(context, "bHaptics/Weapon/Arms/Recoil_LV3_Mirror.tact", PositionType.ForearmL, "pistol_fire", "weapon_fire");
registerFromAsset(context, "bHaptics/Weapon/Vest/Recoil_LV3.tact", PositionType.Right, "pistol_fire", "weapon_fire");
registerFromAsset(context, "bHaptics/Weapon/Arms/Recoil_LV3.tact", PositionType.ForearmR, "pistol_fire", "weapon_fire");
//Shotgun
registerFromAsset(context, "bHaptics/Weapon/Vest/Recoil_LV3_Mirror.tact", PositionType.Left, "shotgun_fire", "weapon_fire");
registerFromAsset(context, "bHaptics/Weapon/Arms/Recoil_LV3_Mirror.tact", PositionType.ForearmL, "shotgun_fire", "weapon_fire");
registerFromAsset(context, "bHaptics/Weapon/Vest/Recoil_LV3.tact", PositionType.Right, "shotgun_fire", "weapon_fire");
registerFromAsset(context, "bHaptics/Weapon/Arms/Recoil_LV3.tact", PositionType.ForearmR, "shotgun_fire", "weapon_fire");
registerFromAsset(context, "bHaptics/Weapon/Vest/Recoil_LV2_Mirror.tact", PositionType.Left, "shotgun_fire", "weapon_fire");
registerFromAsset(context, "bHaptics/Weapon/Arms/Recoil_LV2_Mirror.tact", PositionType.ForearmL, "shotgun_fire", "weapon_fire");
registerFromAsset(context, "bHaptics/Weapon/Vest/Recoil_LV2.tact", PositionType.Right, "shotgun_fire", "weapon_fire");
registerFromAsset(context, "bHaptics/Weapon/Arms/Recoil_LV2.tact", PositionType.ForearmR, "shotgun_fire", "weapon_fire");
//Plasma Gun
registerFromAsset(context, "bHaptics/Weapon/Vest/Recoil_LV1_Mirror.tact", PositionType.Left, "plasmagun_fire", "weapon_fire");
@ -381,11 +408,19 @@ public class bHaptics {
public static void beginFrame()
{
Vector<String> toRemove = new Vector<>();
if (enabled && hasPairedDevice) {
repeatingHaptics.forEach((key, haptic) -> {
//If a repeating haptic isn't playing, start it again
if (!player.isPlaying(haptic.altKey)) {
player.submitRegistered(haptic.key, haptic.altKey, 100, 1.0f, 0, 0);
if (haptic.level == 0) {
if (player.isPlaying(haptic.altKey))
{
player.turnOff(haptic.altKey);
}
}
else if (!player.isPlaying(haptic.altKey)) {
//If a repeating haptic isn't playing, start it again with last known values
float flIntensity = ((haptic.level / 100.0F) * haptic.intensity);
player.submitRegistered(haptic.key, haptic.altKey, flIntensity, haptic.duration, haptic.rotation, 0);
}
});
}
@ -516,7 +551,14 @@ public class bHaptics {
//If this is a repeating event, then add to the set to play in begin frame
if (flags == 1)
{
repeatingHaptics.put(key, haptic);
Haptic repeatingHaptic = new Haptic(haptic);
if (haptic.directional) {
repeatingHaptic.rotation = flAngle;
}
repeatingHaptic.level = intensity;
repeatingHaptics.put(key, repeatingHaptic);
}
else {
player.submitRegistered(haptic.key, haptic.altKey, flIntensity, flDuration, flAngle, yHeight);
@ -554,7 +596,7 @@ public class bHaptics {
key.contains("explode")) {
key = "fireball"; // Just re-use this one
}
else if (key.contains("noair")) {
else if (key.contains("noair") || key.contains("gasp")) {
key = "noair";
}
else if (key.contains("shotgun")) {
@ -595,6 +637,16 @@ public class bHaptics {
{
key = "spark";
}
else if (key.contains("steam"))
{
if (key.contains("blast") || key.contains("shot") || key.contains("chuff")) {
key = "steam_blast";
}
else
{
key = "steam_loop";
}
}
else if (key.contains("player") && key.contains("jump"))
{
key = "jump_start";
@ -623,6 +675,23 @@ public class bHaptics {
}
}
public static void updateRepeatingHaptic(String event, float intensity, float angle) {
if (enabled && hasPairedDevice) {
String key = getHapticEventKey(event);
if (repeatingHaptics.containsKey(key))
{
Haptic haptic = repeatingHaptics.get(key);
if (haptic.directional) {
haptic.rotation = angle;
}
haptic.level = intensity;
}
}
}
public static String read(Context context, String fileName) {
try {