├── Manual
├── warp.jpg
├── scale.jpg
├── leap_warp.gif
├── menu_tool.png
├── play_tool.png
├── warp_tool.png
├── leap_pinch.gif
├── maestro_tool.png
└── laser_pointer.jpg
├── Libs
├── MaestroMode.dll
├── WindowsInput.dll
├── Assembly-CSharp.dll
├── XInputDotNetPure.dll
├── CameraModifications.dll
├── Assembly-CSharp_Studio.dll
└── Injector
│ ├── IllusionPlugin.dll
│ ├── IllusionInjector.dll
│ └── IllusionPlugin.XML
├── .gitmodules
├── PlayClubVR
├── Images
│ └── icon_maestro.png
├── PlayClubSettings.cs
├── Controller.cs
├── PlayClubVoiceCommands.cs
├── Properties
│ └── AssemblyInfo.cs
├── PlayClubVR.cs
├── LookAtMeHandler.cs
├── PlayClubContext.cs
├── PlayClubActor.cs
├── OSP
│ └── OSPAudioVolumeManager.cs
├── TransientHead.cs
├── DynamicColliderRegistry.cs
├── MaestroTool.cs
├── PlayClubStandingMode.cs
├── PlayClubVR.csproj
├── PlayClubInterpreter.cs
├── PlayClubSeatedMode.cs
├── PlayTool.cs
└── ImpersonationHandler.cs
├── GamePadClub
├── Libs
│ └── XInputInterface.dll
├── GamePadHelper.cs
├── GamePadClub.cs
├── Properties
│ └── AssemblyInfo.cs
├── GamePadController.cs
├── Handlers
│ ├── MouseHandler.cs
│ ├── CameraHandler.cs
│ └── GameControlHandler.cs
└── GamePadClub.csproj
├── PlayClubStudioVR
├── StudioActor.cs
├── StudioSeatedMode.cs
├── StudioStandingMode.cs
├── ShisenCorrecter.cs
├── EyeTarget.cs
├── PlayClubStudioVR.cs
├── StudioInterpreter.cs
├── PlayClubStudioVR.csproj
└── IKTool.cs
├── LICENSE
├── PlayClubVR.sln
├── .gitignore
├── README_JA.md
└── README.md
/Manual/warp.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Eusth/PlayClubVR/HEAD/Manual/warp.jpg
--------------------------------------------------------------------------------
/Manual/scale.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Eusth/PlayClubVR/HEAD/Manual/scale.jpg
--------------------------------------------------------------------------------
/Libs/MaestroMode.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Eusth/PlayClubVR/HEAD/Libs/MaestroMode.dll
--------------------------------------------------------------------------------
/Manual/leap_warp.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Eusth/PlayClubVR/HEAD/Manual/leap_warp.gif
--------------------------------------------------------------------------------
/Manual/menu_tool.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Eusth/PlayClubVR/HEAD/Manual/menu_tool.png
--------------------------------------------------------------------------------
/Manual/play_tool.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Eusth/PlayClubVR/HEAD/Manual/play_tool.png
--------------------------------------------------------------------------------
/Manual/warp_tool.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Eusth/PlayClubVR/HEAD/Manual/warp_tool.png
--------------------------------------------------------------------------------
/Libs/WindowsInput.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Eusth/PlayClubVR/HEAD/Libs/WindowsInput.dll
--------------------------------------------------------------------------------
/Manual/leap_pinch.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Eusth/PlayClubVR/HEAD/Manual/leap_pinch.gif
--------------------------------------------------------------------------------
/Manual/maestro_tool.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Eusth/PlayClubVR/HEAD/Manual/maestro_tool.png
--------------------------------------------------------------------------------
/Libs/Assembly-CSharp.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Eusth/PlayClubVR/HEAD/Libs/Assembly-CSharp.dll
--------------------------------------------------------------------------------
/Libs/XInputDotNetPure.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Eusth/PlayClubVR/HEAD/Libs/XInputDotNetPure.dll
--------------------------------------------------------------------------------
/Manual/laser_pointer.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Eusth/PlayClubVR/HEAD/Manual/laser_pointer.jpg
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "VRGIN"]
2 | path = VRGIN
3 | url = https://github.com/Eusth/VRGIN.Core.git
4 |
--------------------------------------------------------------------------------
/Libs/CameraModifications.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Eusth/PlayClubVR/HEAD/Libs/CameraModifications.dll
--------------------------------------------------------------------------------
/Libs/Assembly-CSharp_Studio.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Eusth/PlayClubVR/HEAD/Libs/Assembly-CSharp_Studio.dll
--------------------------------------------------------------------------------
/Libs/Injector/IllusionPlugin.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Eusth/PlayClubVR/HEAD/Libs/Injector/IllusionPlugin.dll
--------------------------------------------------------------------------------
/Libs/Injector/IllusionInjector.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Eusth/PlayClubVR/HEAD/Libs/Injector/IllusionInjector.dll
--------------------------------------------------------------------------------
/PlayClubVR/Images/icon_maestro.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Eusth/PlayClubVR/HEAD/PlayClubVR/Images/icon_maestro.png
--------------------------------------------------------------------------------
/GamePadClub/Libs/XInputInterface.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Eusth/PlayClubVR/HEAD/GamePadClub/Libs/XInputInterface.dll
--------------------------------------------------------------------------------
/PlayClubVR/PlayClubSettings.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Xml.Serialization;
6 | using VRGIN.Core;
7 |
8 | namespace PlayClubVR
9 | {
10 | [XmlRoot("Settings")]
11 | public class PlayClubSettings : VRSettings
12 | {
13 |
14 | public bool FullImpersonation { get; set; }
15 |
16 | ///
17 | /// Sets or gets whether or not the girls should look at the player by default.
18 | ///
19 | public bool AutoLookAtMe { get { return _AutoLookAtMe; } set { _AutoLookAtMe = value; TriggerPropertyChanged("AutoLookAtMe"); } }
20 | private bool _AutoLookAtMe = true;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/PlayClubStudioVR/StudioActor.cs:
--------------------------------------------------------------------------------
1 | using PlayClubVR;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using VRGIN.Core;
7 |
8 | namespace PlayClubStudioVR
9 | {
10 | public class StudioActor : PlayClubActor
11 | {
12 | public StudioActor(Human nativeActor) : base(nativeActor)
13 | {
14 | }
15 |
16 | protected override void Initialize(Human actor)
17 | {
18 | base.Initialize(actor);
19 |
20 | if(actor.sex == Human.SEX.FEMALE)
21 | {
22 | var correcter = actor.gameObject.AddComponent();
23 | correcter.Actor = this;
24 | Logger.Info("Attached Shisen Correcter to {0}", actor.CharaType);
25 | }
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/PlayClubStudioVR/StudioSeatedMode.cs:
--------------------------------------------------------------------------------
1 | using PlayClubVR;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using VRGIN.Core;
7 |
8 | namespace PlayClubStudioVR
9 | {
10 | class StudioSeatedMode : PlayClubSeatedMode
11 | {
12 | protected override void ChangeMode()
13 | {
14 | VR.Manager.SetMode();
15 | }
16 |
17 | public override IEnumerable Tools
18 | {
19 | get
20 | {
21 | return base.Tools
22 | // Remove unneeded
23 | .Except((new Type[] { typeof(PlayTool), typeof(MaestroTool) }))
24 | // Add new
25 | .Concat(new Type[] { typeof(IKTool) });
26 | }
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/PlayClubVR/Controller.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using UnityEngine;
6 | using VRGIN.Core;
7 | using VRGIN.Controls;
8 |
9 | namespace PlayClubVR
10 | {
11 | public class PlayClubController : Controller
12 | {
13 | public static PlayClubController Create()
14 | {
15 | var leftHand = new GameObject("A Controller").AddComponent();
16 |
17 | return leftHand;
18 | }
19 |
20 |
21 | //void OnTriggerEnter(Collider collider)
22 | //{
23 | // var boneCollider = collider.GetComponentInChildren();
24 | // if(boneCollider)
25 | // {
26 | // boneCollider.Collide()
27 | // }
28 | //}
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/GamePadClub/GamePadHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using XInputDotNetPure;
6 |
7 | namespace GamePadClub
8 | {
9 | public static class GamePadHelper
10 | {
11 | public static bool IsPressDown(ButtonState now, ButtonState before)
12 | {
13 | return now == ButtonState.Pressed && before == ButtonState.Released;
14 | }
15 |
16 | public static bool IsPressUp(ButtonState now, ButtonState before)
17 | {
18 | return now == ButtonState.Released && before == ButtonState.Pressed;
19 | }
20 |
21 | public static bool IsShoulderPressed(GamePadState state)
22 | {
23 | return state.Buttons.LeftShoulder == ButtonState.Pressed || state.Buttons.RightShoulder == ButtonState.Pressed;
24 | }
25 |
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/PlayClubStudioVR/StudioStandingMode.cs:
--------------------------------------------------------------------------------
1 | using PlayClubVR;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using VRGIN.Core;
7 |
8 | namespace PlayClubStudioVR
9 | {
10 | class StudioStandingMode : PlayClubStandingMode
11 | {
12 | protected override void ChangeMode()
13 | {
14 | VR.Manager.SetMode();
15 | }
16 |
17 | protected override void CreateControllers()
18 | {
19 | base.CreateControllers();
20 | }
21 |
22 | public override IEnumerable Tools
23 | {
24 | get
25 | {
26 | return base.Tools
27 | // Remove unneeded
28 | .Except((new Type[] { typeof(PlayTool), typeof(MaestroTool) }))
29 | // Add new
30 | .Concat(new Type[] { typeof(IKTool) });
31 | }
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Eusth
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/GamePadClub/GamePadClub.cs:
--------------------------------------------------------------------------------
1 | using GamePadClub.Handlers;
2 | using IllusionPlugin;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Text;
7 |
8 | namespace GamePadClub
9 | {
10 | public class GamePadClub : IPlugin
11 | {
12 | public string Name
13 | {
14 | get
15 | {
16 | return "GamePadClub";
17 | }
18 | }
19 |
20 | public string Version
21 | {
22 | get
23 | {
24 | return "0.1";
25 | }
26 | }
27 |
28 | public void OnApplicationQuit()
29 | {
30 | }
31 |
32 | public void OnApplicationStart()
33 | {
34 | var instance = GamePadController.Instance;
35 | instance.gameObject.AddComponent();
36 | instance.gameObject.AddComponent();
37 | instance.gameObject.AddComponent();
38 | }
39 |
40 | public void OnFixedUpdate()
41 | {
42 | }
43 |
44 | public void OnLevelWasInitialized(int level)
45 | {
46 | }
47 |
48 | public void OnLevelWasLoaded(int level)
49 | {
50 | }
51 |
52 | public void OnUpdate()
53 | {
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/PlayClubVR/PlayClubVoiceCommands.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using VRGIN.Controls.Speech;
6 |
7 | namespace PlayClubVR
8 | {
9 | public class PlayClubVoiceCommand : VoiceCommand
10 | {
11 | public static readonly VoiceCommand NextAnimation = new PlayClubVoiceCommand("next");
12 | public static readonly VoiceCommand PreviousAnimation = new PlayClubVoiceCommand("previous");
13 | public static readonly VoiceCommand StartAnimation = new PlayClubVoiceCommand("start");
14 | public static readonly VoiceCommand StopAnimation = new PlayClubVoiceCommand("stop");
15 | public static readonly VoiceCommand Faster = new PlayClubVoiceCommand("faster", "increase speed");
16 | public static readonly VoiceCommand Slower = new PlayClubVoiceCommand("slower", "decrease speed");
17 | public static readonly VoiceCommand Climax = new PlayClubVoiceCommand("climax", "come");
18 | public static readonly VoiceCommand DisableClimax = new PlayClubVoiceCommand("disable climax", "disable orgasm");
19 | public static readonly VoiceCommand EnableClimax = new PlayClubVoiceCommand("enable climax", "enable orgasm");
20 |
21 | protected PlayClubVoiceCommand(params string[] texts) : base(texts)
22 | {
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/GamePadClub/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("GamePadClub")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("GamePadClub")]
13 | [assembly: AssemblyCopyright("Copyright © 2016")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("8cf2e8ae-b1ca-4b00-b997-74622bdaf627")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/PlayClubStudioVR/ShisenCorrecter.cs:
--------------------------------------------------------------------------------
1 | using PlayClubVR;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Reflection;
6 | using System.Text;
7 | using UnityEngine;
8 | using VRGIN.Core;
9 |
10 | namespace PlayClubStudioVR
11 | {
12 | class ShisenCorrecter : MonoBehaviour {
13 |
14 | private Human _Human;
15 | public PlayClubActor Actor;
16 |
17 | void Start()
18 | {
19 | _Human = GetComponent();
20 | }
21 |
22 |
23 | void Update()
24 | {
25 | if (!_Human) return;
26 |
27 | var eyeLookCtrl = _Human.eyeLook;
28 | var targetCtrl = _Human.bodyRoot.GetComponent();
29 |
30 | // Make a new EyeTargetController if required
31 | if (targetCtrl == null)
32 | {
33 | targetCtrl = _Human.bodyRoot.gameObject.AddComponent();
34 | targetCtrl.rootNode = Actor.Eyes;
35 | }
36 |
37 | // Replace camera targets if required
38 | if (eyeLookCtrl.Target.camera == Camera.main)
39 | {
40 | eyeLookCtrl.Change(LookAtRotator.TYPE.TARGET, targetCtrl.Target, true);
41 | }
42 |
43 | var neckLookCtrl = _Human.neckLook;
44 | if (neckLookCtrl.Target.camera == Camera.main)
45 | {
46 | neckLookCtrl.Change(LookAtRotator.TYPE.TARGET, targetCtrl.Target, true);
47 | }
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/PlayClubVR/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("PlayClubVR")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("PlayClubVR")]
13 | [assembly: AssemblyCopyright("Copyright © 2016")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("3b4fb983-3996-455b-a81b-d0c023f3fbbc")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/PlayClubStudioVR/EyeTarget.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using UnityEngine;
6 | using VRGIN.Core;
7 |
8 | namespace PlayClubStudioVR
9 | {
10 | /**
11 | * Manages the eye target for a single female.
12 | */
13 | class EyeTargetController : MonoBehaviour
14 | {
15 | public Transform Target { get; private set; }
16 | public Transform rootNode;
17 | private EyeTarget eyeTarget;
18 |
19 | void Start()
20 | {
21 | Target = new GameObject().transform;
22 |
23 | eyeTarget = Target.gameObject.AddComponent();
24 | eyeTarget.rootNode = rootNode;
25 | }
26 |
27 |
28 | void OnDestroy()
29 | {
30 | // Character was destroyed, so destroy the created target!
31 | Destroy(Target.gameObject);
32 | }
33 | }
34 |
35 | ///
36 | /// Represents a target that can be looked at.
37 | ///
38 | class EyeTarget : MonoBehaviour
39 | {
40 | ///
41 | /// Offset in meters from the camera.
42 | ///
43 | public float offset = 0.5f;
44 |
45 | ///
46 | /// Origin of the gaze.
47 | ///
48 | public Transform rootNode;
49 |
50 | void Update()
51 | {
52 | if (rootNode != null)
53 | {
54 | var camera = VR.Camera.SteamCam.head.transform;
55 | var dir = (camera.position - rootNode.position).normalized;
56 |
57 | transform.position = camera.position + dir * offset;
58 | }
59 |
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/PlayClubVR/PlayClubVR.cs:
--------------------------------------------------------------------------------
1 | using IllusionPlugin;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using VRGIN.Core;
7 | using VRGIN.Modes;
8 |
9 | namespace PlayClubVR
10 | {
11 | public class PlayClubVR : IEnhancedPlugin
12 | {
13 | public string[] Filter
14 | {
15 | get
16 | {
17 | return new string[] { "PlayClub" };
18 | }
19 | }
20 |
21 | public string Name
22 | {
23 | get
24 | {
25 | return "PlayClubVR";
26 | }
27 | }
28 |
29 | public string Version
30 | {
31 | get
32 | {
33 | return "0.5";
34 | }
35 | }
36 |
37 | public void OnApplicationQuit()
38 | {
39 | }
40 |
41 | public void OnApplicationStart()
42 | {
43 | if (Environment.CommandLine.Contains("--vr"))
44 | {
45 | var manager = VRManager.Create(new PlayClubContext());
46 | manager.SetMode();
47 | }
48 | if(Environment.CommandLine.Contains("--verbose"))
49 | {
50 | Logger.Level = Logger.LogMode.Debug;
51 | }
52 | }
53 |
54 | public void OnFixedUpdate()
55 | {
56 | }
57 |
58 | public void OnLateUpdate()
59 | {
60 | }
61 |
62 | public void OnLevelWasInitialized(int level)
63 | {
64 | }
65 |
66 | public void OnLevelWasLoaded(int level)
67 | {
68 | }
69 |
70 | public void OnUpdate()
71 | {
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/PlayClubStudioVR/PlayClubStudioVR.cs:
--------------------------------------------------------------------------------
1 | using IllusionPlugin;
2 | using PlayClubVR;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Text;
7 | using VRGIN.Core;
8 |
9 | namespace PlayClubStudioVR
10 | {
11 | public class PlayClubStudioVR : IEnhancedPlugin
12 | {
13 | public string[] Filter
14 | {
15 | get
16 | {
17 | return new string[] { "PlayClubStudio" };
18 | }
19 | }
20 |
21 | public string Name
22 | {
23 | get
24 | {
25 | return "Play Club Studio VR";
26 | }
27 | }
28 |
29 | public string Version
30 | {
31 | get
32 | {
33 | return "0.5";
34 | }
35 | }
36 |
37 | public void OnApplicationQuit()
38 | {
39 |
40 | }
41 |
42 | public void OnApplicationStart()
43 | {
44 | if (Environment.CommandLine.Contains("--vr"))
45 | {
46 | var manager = VRManager.Create(new PlayClubContext());
47 | manager.SetMode();
48 | }
49 | if (Environment.CommandLine.Contains("--verbose"))
50 | {
51 | Logger.Level = Logger.LogMode.Debug;
52 | }
53 | }
54 |
55 | public void OnFixedUpdate()
56 | {
57 | }
58 |
59 | public void OnLateUpdate()
60 | {
61 | }
62 |
63 | public void OnLevelWasInitialized(int level)
64 | {
65 | }
66 |
67 | public void OnLevelWasLoaded(int level)
68 | {
69 | }
70 |
71 | public void OnUpdate()
72 | {
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/PlayClubVR/LookAtMeHandler.cs:
--------------------------------------------------------------------------------
1 | using CameraModifications;
2 | using IllusionInjector;
3 | using System;
4 | using System.Collections;
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using System.Text;
8 | using VRGIN.Core;
9 |
10 | namespace PlayClubVR
11 | {
12 | class LookAtMeHandler : ProtectedBehaviour
13 | {
14 |
15 | //CameraModifications.KocchiMitePlugin _KocchitMite;
16 |
17 | protected override void OnStart()
18 | {
19 | base.OnStart();
20 | if(!PluginManager.Plugins.Any(plugin => plugin.GetType().FullName == "CameraModifications.KocchiMitePlugin"))
21 | {
22 | VRLog.Warn("Didn't find Kocchi Mite plugin");
23 |
24 | enabled = false;
25 | return;
26 | }
27 |
28 | VRLog.Info("Found Kocchi Mite plugin");
29 |
30 | }
31 |
32 | protected override void OnLevel(int level)
33 | {
34 | base.OnLevel(level);
35 |
36 | if ((VR.Settings as PlayClubSettings).AutoLookAtMe) {
37 | StartCoroutine(WaitALittle(delegate
38 | {
39 | VRLog.Info("Setting gaze to camera");
40 | KocchiMite.HeadLookType = LookAtRotator.TYPE.TARGET;
41 | KocchiMite.LookType = LookAtRotator.TYPE.TARGET;
42 | }));
43 | }
44 | }
45 |
46 | private KocchiMitePlugin KocchiMite
47 | {
48 | get
49 | {
50 | return PluginManager.Plugins.OfType().First();
51 | }
52 | }
53 |
54 | IEnumerator WaitALittle(Action action)
55 | {
56 | yield return null;
57 | yield return null;
58 |
59 | action();
60 | }
61 |
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/GamePadClub/GamePadController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using UnityEngine;
6 | using XInputDotNetPure;
7 |
8 | namespace GamePadClub
9 | {
10 | public class GamePadController : MonoBehaviour
11 | {
12 | public delegate bool GamePadConsumer(GamePadState nowState, GamePadState prevState);
13 |
14 | private static GamePadController _Instance;
15 | private List _Consumers = new List();
16 |
17 | private GamePadState? _PrevState;
18 |
19 | public static GamePadController Instance
20 | {
21 | get
22 | {
23 | if (!_Instance)
24 | {
25 | _Instance = new GameObject("GamePadClub_Controller").AddComponent();
26 | DontDestroyOnLoad(_Instance.gameObject);
27 | }
28 | return _Instance;
29 | }
30 | }
31 |
32 | public void Register(GamePadConsumer consumer)
33 | {
34 | _Consumers.Add(consumer);
35 | }
36 |
37 | public void RegisterAtStart(GamePadConsumer consumer)
38 | {
39 | _Consumers.Insert(0, consumer);
40 | }
41 | public bool Unregister(GamePadConsumer consumer)
42 | {
43 | return _Consumers.Remove(consumer);
44 | }
45 |
46 |
47 | public void FixedUpdate()
48 | {
49 | GamePadState state = GamePad.GetState(PlayerIndex.One);
50 |
51 | if (_PrevState != null && state.IsConnected)
52 | {
53 | foreach (var consumer in _Consumers)
54 | {
55 | if (consumer(state, _PrevState.Value))
56 | {
57 | break;
58 | }
59 | }
60 | }
61 |
62 | _PrevState = state;
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/GamePadClub/Handlers/MouseHandler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using UnityEngine;
6 | using WindowsInput;
7 | using XInputDotNetPure;
8 |
9 | namespace GamePadClub.Handlers
10 | {
11 | public class MouseHandler : MonoBehaviour
12 | {
13 | private const float TRIGGER_THRESHOLD = 0.5f;
14 | InputSimulator _Input;
15 |
16 | void Awake()
17 | {
18 | _Input = new InputSimulator();
19 | }
20 |
21 | void OnEnable()
22 | {
23 | GamePadController.Instance.Register(MoveMouse);
24 | GamePadController.Instance.Register(HandleClicks);
25 | }
26 |
27 | void OnDisable()
28 | {
29 | GamePadController.Instance.Unregister(HandleClicks);
30 | GamePadController.Instance.Unregister(MoveMouse);
31 | }
32 |
33 | bool HandleClicks(GamePadState now, GamePadState before)
34 | {
35 | if (GamePadHelper.IsShoulderPressed(now)) return false;
36 |
37 | // Left click
38 | if (GamePadHelper.IsPressDown(now.Buttons.A, before.Buttons.A))
39 | {
40 | _Input.Mouse.LeftButtonDown();
41 | }
42 | else if (GamePadHelper.IsPressUp(now.Buttons.A, before.Buttons.A))
43 | {
44 | _Input.Mouse.LeftButtonUp();
45 | }
46 |
47 | // Right click
48 | if (GamePadHelper.IsPressDown(now.Buttons.B, before.Buttons.B))
49 | {
50 | _Input.Mouse.RightButtonDown();
51 | }
52 | else if (GamePadHelper.IsPressUp(now.Buttons.B, before.Buttons.B))
53 | {
54 | _Input.Mouse.RightButtonUp();
55 | }
56 |
57 | return false;
58 | }
59 |
60 | bool MoveMouse(GamePadState now, GamePadState before)
61 | {
62 | if (now.Triggers.Left < TRIGGER_THRESHOLD && now.Triggers.Right < TRIGGER_THRESHOLD && !GamePadHelper.IsShoulderPressed(now))
63 | {
64 | // Move cursor
65 | _Input.Mouse.MoveMouseBy((int)(now.ThumbSticks.Left.X * Time.deltaTime * 700),
66 | (int)(-now.ThumbSticks.Left.Y * Time.deltaTime * 700));
67 | }
68 |
69 | return false;
70 | }
71 |
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/PlayClubVR/PlayClubContext.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using UnityEngine;
6 | using VRGIN.Controls.Speech;
7 | using VRGIN.Core;
8 | using VRGIN.Visuals;
9 |
10 | namespace PlayClubVR
11 | {
12 | public class PlayClubContext : IVRManagerContext
13 | {
14 |
15 | private DefaultMaterialPalette _Materials;
16 | private VRSettings _Settings;
17 |
18 | public PlayClubContext()
19 | {
20 | _Materials = new DefaultMaterialPalette();
21 | _Settings = VRSettings.Load("vr_settings.xml");
22 |
23 | _Materials.StandardShader = Shader.Find("Marmoset/Specular IBL");
24 | }
25 |
26 | public string GuiLayer
27 | {
28 | get
29 | {
30 | return "Ignore Raycast";
31 | }
32 | }
33 |
34 | public string InvisibleLayer
35 | {
36 | get
37 | {
38 | return "ScreenShot";
39 | }
40 | }
41 |
42 | public IMaterialPalette Materials
43 | {
44 | get
45 | {
46 | return _Materials;
47 | }
48 | }
49 |
50 | public Color PrimaryColor
51 | {
52 | get
53 | {
54 | return Color.cyan;
55 | }
56 | }
57 |
58 | public VRSettings Settings
59 | {
60 | get
61 | {
62 | return _Settings;
63 | }
64 | }
65 |
66 | public int UILayerMask
67 | {
68 | get
69 | {
70 | return LayerMask.GetMask(UILayer);
71 | }
72 | }
73 |
74 | public string UILayer
75 | {
76 | get
77 | {
78 | return "UI";
79 | }
80 | }
81 |
82 | public bool SimulateCursor
83 | {
84 | get
85 | {
86 | return false;
87 | }
88 | }
89 |
90 | public bool GUIAlternativeSortingMode
91 | {
92 | get
93 | {
94 | return true;
95 | }
96 | }
97 |
98 | public Type VoiceCommandType
99 | {
100 | get
101 | {
102 | return typeof(PlayClubVoiceCommand);
103 | }
104 | }
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/PlayClubStudioVR/StudioInterpreter.cs:
--------------------------------------------------------------------------------
1 | using PlayClubVR;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using UnityEngine;
7 | using VRGIN.Core;
8 |
9 | namespace PlayClubStudioVR
10 | {
11 | public class StudioInterpreter : GameInterpreter
12 | {
13 | public StudioScene _Scene;
14 |
15 | private List _Actors = new List();
16 | private readonly int pngLayer = LayerMask.NameToLayer("PNG");
17 | public override IEnumerable Actors
18 | {
19 | get { return _Actors; }
20 | }
21 |
22 | protected override void OnStart()
23 | {
24 | base.OnStart();
25 | InitScene();
26 | }
27 |
28 |
29 | protected override void OnLevel(int level)
30 | {
31 | base.OnLevel(level);
32 | InitScene();
33 | }
34 |
35 | protected override void OnUpdate()
36 | {
37 | base.OnUpdate();
38 |
39 | if (_Scene)
40 | {
41 | CleanActors();
42 | }
43 | else
44 | {
45 | _Actors.Clear();
46 | }
47 | }
48 |
49 | public override IEnumerable FindSubCameras()
50 | {
51 | var subCams = Camera.allCameras.Where(
52 | cam => (cam.cullingMask & VR.Context.UILayerMask) == 0
53 | && cam.clearFlags != CameraClearFlags.Color).ToArray();
54 |
55 | Logger.Info("Found {0} sub cameras", subCams.Length);
56 | return subCams;
57 | }
58 |
59 | ///
60 | /// Removes dead entries from actors list and adds new ones.
61 | ///
62 | private void CleanActors()
63 | {
64 | _Actors = Actors.Where(a => a.IsValid).ToList();
65 |
66 | foreach (var member in _Scene.charas.Humans)
67 | {
68 | AddActor(member.human);
69 | }
70 | }
71 |
72 | public override bool IsIgnoredCanvas(Canvas canvas)
73 | {
74 | return canvas.gameObject.layer == pngLayer;
75 | }
76 |
77 | private void AddActor(Human member)
78 | {
79 | if (!member.GetComponent())
80 | {
81 | _Actors.Add(new StudioActor(member));
82 | }
83 | }
84 |
85 | private void InitScene()
86 | {
87 | _Scene = GameObject.FindObjectOfType();
88 |
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/PlayClubVR/PlayClubActor.cs:
--------------------------------------------------------------------------------
1 | using PlayClubVR.OSP;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Reflection;
6 | using System.Text;
7 | using UnityEngine;
8 | using VRGIN.Core;
9 | using VRGIN.Helpers;
10 |
11 | namespace PlayClubVR
12 | {
13 | public class PlayClubActor : DefaultActor
14 | {
15 |
16 | private static FieldInfo _HeartField = typeof(HumanVoice).GetField("heart", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
17 | private static FieldInfo _VoiceField = typeof(HumanVoice).GetField("voice", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
18 | private Transform _EyeTransform;
19 | private TransientHead _Head;
20 |
21 | public PlayClubActor(Human nativeActor) : base(nativeActor)
22 | {
23 | }
24 |
25 | public override Transform Eyes
26 | {
27 | get
28 | {
29 | return _EyeTransform;
30 | }
31 | }
32 |
33 | public override bool HasHead
34 | {
35 | get
36 | {
37 | return _Head.Visible;
38 | }
39 | set
40 | {
41 | _Head.Visible = value;
42 | }
43 | }
44 |
45 | protected override void Initialize(Human actor)
46 | {
47 | base.Initialize(actor);
48 |
49 | // Get position of actor's eyes
50 | _Head = Actor.gameObject.AddComponent();
51 | _EyeTransform = TransientHead.GetEyes(Actor);
52 |
53 | // 3D-ize actor's voice
54 | if (actor.voice)
55 | {
56 | _HeartField.SetValue(actor.voice, OSPAudioVolumeManager.Create(_HeartField.GetValue(actor.voice) as AudioVolumeManager));
57 | _VoiceField.SetValue(actor.voice, OSPAudioVolumeManager.Create(_VoiceField.GetValue(actor.voice) as AudioVolumeManager));
58 | }
59 |
60 | // Register bones
61 | foreach (var bone in SoftCustomBones)
62 | {
63 | DynamicColliderRegistry.RegisterDynamicBone(bone);
64 | }
65 | foreach (var bone in SoftBones)
66 | {
67 | DynamicColliderRegistry.RegisterDynamicBone(bone);
68 | }
69 | }
70 |
71 | public IEnumerable SoftBones
72 | {
73 | get
74 | {
75 | return Actor.GetComponentsInChildren();
76 | }
77 | }
78 |
79 | public IEnumerable SoftCustomBones
80 | {
81 | get
82 | {
83 | return Actor.GetComponentsInChildren();
84 | }
85 | }
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/PlayClubVR/OSP/OSPAudioVolumeManager.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using UnityEngine;
6 |
7 | namespace PlayClubVR.OSP
8 | {
9 | class OSPAudioVolumeManager : AudioVolumeManager
10 | {
11 | private OSPAudioSource ospSource;
12 |
13 | public OSPAudioVolumeManager(AudioSource source, Human human) : base(source, human)
14 | {
15 | }
16 |
17 | public static OSPAudioVolumeManager Create(AudioVolumeManager blueprint)
18 | {
19 | var sourceField = typeof(AudioVolumeManager).GetField("source", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
20 | var humanField = typeof(AudioVolumeManager).GetField("human", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
21 |
22 | var manager = new OSPAudioVolumeManager(sourceField.GetValue(blueprint) as AudioSource, humanField.GetValue(blueprint) as Human);
23 | manager.ospSource = manager.source.gameObject.AddComponent();
24 | return manager;
25 | }
26 |
27 | public override void Play(float fade)
28 | {
29 | this.ospSource.Play();
30 | if (fade == 0f)
31 | {
32 | this.rate = 1f;
33 | this.move = 0f;
34 | }
35 | else
36 | {
37 | this.rate = 0f;
38 | this.move = 1f / fade;
39 | }
40 | this.CalcVolume();
41 | }
42 |
43 | public override void PlayDelay(float fade, float delay)
44 | {
45 | ospSource.PlayDelayed(delay);
46 | if (fade == 0f)
47 | {
48 | this.rate = 1f;
49 | this.move = 0f;
50 | }
51 | else
52 | {
53 | this.rate = 0f;
54 | this.move = 1f / fade;
55 | }
56 | this.CalcVolume();
57 | }
58 |
59 | public override void Update()
60 | {
61 | if (this.move != 0f)
62 | {
63 | this.rate += this.move * Time.deltaTime;
64 | if (this.move > 0f && this.rate >= 1f)
65 | {
66 | this.rate = 1f;
67 | this.move = 0f;
68 | }
69 | else if (this.move < 0f && this.rate <= 0f)
70 | {
71 | this.rate = 0f;
72 | this.move = 0f;
73 | this.ospSource.Stop();
74 | }
75 | }
76 | this.CalcVolume();
77 | }
78 |
79 | public override void PlayDelay(AudioClip clip, bool loop, float fade, float delay)
80 | {
81 | this.ospSource.Stop();
82 | this.source.clip = clip;
83 | this.source.loop = loop;
84 | this.ospSource.Stop();
85 | this.PlayDelay(fade, delay);
86 | }
87 |
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/PlayClubVR.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.25123.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlayClubVR", "PlayClubVR\PlayClubVR.csproj", "{BE0FD119-262B-42C0-BE1F-8BCE0AF022D8}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VRGIN.U46", "VRGIN\VRGIN\VRGIN.U46.csproj", "{8FE87229-42A4-4CB0-846A-7A2726569B17}"
9 | EndProject
10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlayClubStudioVR", "PlayClubStudioVR\PlayClubStudioVR.csproj", "{9F6E1BC0-2C48-433E-A8C7-5C21DB635C99}"
11 | EndProject
12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GamePadClub", "GamePadClub\GamePadClub.csproj", "{8CF2E8AE-B1CA-4B00-B997-74622BDAF627}"
13 | EndProject
14 | Global
15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
16 | Debug|Any CPU = Debug|Any CPU
17 | Install|Any CPU = Install|Any CPU
18 | Release|Any CPU = Release|Any CPU
19 | EndGlobalSection
20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
21 | {BE0FD119-262B-42C0-BE1F-8BCE0AF022D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
22 | {BE0FD119-262B-42C0-BE1F-8BCE0AF022D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
23 | {BE0FD119-262B-42C0-BE1F-8BCE0AF022D8}.Install|Any CPU.ActiveCfg = Install|Any CPU
24 | {BE0FD119-262B-42C0-BE1F-8BCE0AF022D8}.Install|Any CPU.Build.0 = Install|Any CPU
25 | {BE0FD119-262B-42C0-BE1F-8BCE0AF022D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
26 | {BE0FD119-262B-42C0-BE1F-8BCE0AF022D8}.Release|Any CPU.Build.0 = Release|Any CPU
27 | {8FE87229-42A4-4CB0-846A-7A2726569B17}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
28 | {8FE87229-42A4-4CB0-846A-7A2726569B17}.Debug|Any CPU.Build.0 = Debug|Any CPU
29 | {8FE87229-42A4-4CB0-846A-7A2726569B17}.Install|Any CPU.ActiveCfg = Release|Any CPU
30 | {8FE87229-42A4-4CB0-846A-7A2726569B17}.Install|Any CPU.Build.0 = Release|Any CPU
31 | {8FE87229-42A4-4CB0-846A-7A2726569B17}.Release|Any CPU.ActiveCfg = Release|Any CPU
32 | {8FE87229-42A4-4CB0-846A-7A2726569B17}.Release|Any CPU.Build.0 = Release|Any CPU
33 | {9F6E1BC0-2C48-433E-A8C7-5C21DB635C99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
34 | {9F6E1BC0-2C48-433E-A8C7-5C21DB635C99}.Debug|Any CPU.Build.0 = Debug|Any CPU
35 | {9F6E1BC0-2C48-433E-A8C7-5C21DB635C99}.Install|Any CPU.ActiveCfg = Install|Any CPU
36 | {9F6E1BC0-2C48-433E-A8C7-5C21DB635C99}.Install|Any CPU.Build.0 = Install|Any CPU
37 | {9F6E1BC0-2C48-433E-A8C7-5C21DB635C99}.Release|Any CPU.ActiveCfg = Release|Any CPU
38 | {9F6E1BC0-2C48-433E-A8C7-5C21DB635C99}.Release|Any CPU.Build.0 = Release|Any CPU
39 | {8CF2E8AE-B1CA-4B00-B997-74622BDAF627}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
40 | {8CF2E8AE-B1CA-4B00-B997-74622BDAF627}.Debug|Any CPU.Build.0 = Debug|Any CPU
41 | {8CF2E8AE-B1CA-4B00-B997-74622BDAF627}.Install|Any CPU.ActiveCfg = Release|Any CPU
42 | {8CF2E8AE-B1CA-4B00-B997-74622BDAF627}.Install|Any CPU.Build.0 = Release|Any CPU
43 | {8CF2E8AE-B1CA-4B00-B997-74622BDAF627}.Release|Any CPU.ActiveCfg = Release|Any CPU
44 | {8CF2E8AE-B1CA-4B00-B997-74622BDAF627}.Release|Any CPU.Build.0 = Release|Any CPU
45 | EndGlobalSection
46 | GlobalSection(SolutionProperties) = preSolution
47 | HideSolutionNode = FALSE
48 | EndGlobalSection
49 | EndGlobal
50 |
--------------------------------------------------------------------------------
/GamePadClub/Handlers/CameraHandler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Reflection;
6 | using System.Text;
7 | using UnityEngine;
8 | using WindowsInput;
9 | using XInputDotNetPure;
10 |
11 | namespace GamePadClub.Handlers
12 | {
13 | public class CameraHandler : MonoBehaviour
14 | {
15 | private const float TRIGGER_THRESHOLD = 0.8f;
16 |
17 | private IllusionCamera _Camera;
18 | private FieldInfo _DistanceField = typeof(IllusionCamera).GetField("distance", BindingFlags.NonPublic | BindingFlags.Instance);
19 | private Queue _Messages = new Queue();
20 | void OnEnable()
21 | {
22 | GamePadController.Instance.Register(MoveCamera);
23 | }
24 |
25 | void OnDisable()
26 | {
27 | GamePadController.Instance.Unregister(MoveCamera);
28 | }
29 |
30 | void Start()
31 | {
32 | StartCoroutine(HandleMessages());
33 | }
34 |
35 | public void OnLevelWasLoaded()
36 | {
37 | _Camera = FindObjectOfType();
38 | }
39 |
40 | bool MoveCamera(GamePadState state, GamePadState prevState)
41 | {
42 | if (GamePadHelper.IsShoulderPressed(state)) return false;
43 |
44 | if (_Camera)
45 | {
46 | var leftThumb = new Vector2(state.ThumbSticks.Left.X, state.ThumbSticks.Left.Y);
47 | var rightThumb = new Vector2(state.ThumbSticks.Right.X, state.ThumbSticks.Right.Y);
48 | bool leftTrigger = state.Triggers.Left > TRIGGER_THRESHOLD;
49 | bool rightTrigger = state.Triggers.Right > TRIGGER_THRESHOLD;
50 |
51 | if (leftTrigger || rightTrigger)
52 | {
53 | // Zoom
54 | _DistanceField.SetValue(_Camera, Mathf.Max(0.1f, _Camera.Distance - rightThumb.y * Time.deltaTime * 2));
55 |
56 | _Messages.Enqueue(() =>
57 | {
58 | _Camera.Rotate(new Vector3(0, -rightThumb.x, 0) * Time.deltaTime * 100);
59 | });
60 | }
61 | if (leftTrigger)
62 | {
63 | // Pan 1
64 | _Camera.Translate(leftThumb * Time.deltaTime * 100, false);
65 |
66 | }
67 | else if (rightTrigger)
68 | {
69 | // Pan 2
70 | _Camera.Translate(new Vector3(leftThumb.x, 0, leftThumb.y) * Time.deltaTime * 100, false);
71 |
72 | }
73 | else
74 | {
75 | // Move
76 | _Messages.Enqueue(() =>
77 | {
78 | _Camera.Rotate(new Vector3(rightThumb.y, -rightThumb.x, 0) * Time.deltaTime * 100);
79 | });
80 | }
81 | }
82 | return false;
83 | }
84 |
85 | IEnumerator HandleMessages()
86 | {
87 | //Console.WriteLine("Starting message queue");
88 | while(true)
89 | {
90 | //Console.WriteLine("Iterate");
91 | // This code is executed between Update() and LateUpdate()
92 | // We do this to not interfere with the VR mod
93 | while (_Messages.Count > 0)
94 | {
95 | //Console.WriteLine("Dequeue");
96 |
97 | _Messages.Dequeue()();
98 | }
99 | yield return null;
100 | }
101 | }
102 | }
103 |
104 | }
105 |
--------------------------------------------------------------------------------
/GamePadClub/GamePadClub.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {8CF2E8AE-B1CA-4B00-B997-74622BDAF627}
8 | Library
9 | Properties
10 | GamePadClub
11 | GamePadClub
12 | v3.5
13 | 512
14 |
15 |
16 | true
17 | full
18 | false
19 | bin\Debug\
20 | DEBUG;TRACE
21 | prompt
22 | 4
23 |
24 |
25 | pdbonly
26 | true
27 | bin\Release\
28 | TRACE
29 | prompt
30 | 4
31 |
32 |
33 |
34 | ..\Libs\Assembly-CSharp.dll
35 | False
36 |
37 |
38 | ..\Libs\Injector\IllusionPlugin.dll
39 | False
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | ..\VRGIN\Libs\Unity 4.6\UnityEngine.dll
49 | False
50 |
51 |
52 | ..\VRGIN\Libs\Unity 4.6\UnityEngine.UI.dll
53 | False
54 |
55 |
56 | ..\Libs\WindowsInput.dll
57 |
58 |
59 | ..\Libs\XInputDotNetPure.dll
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | PreserveNewest
75 |
76 |
77 |
78 |
85 |
--------------------------------------------------------------------------------
/PlayClubVR/TransientHead.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using UnityEngine;
6 | using VRGIN.Core;
7 |
8 | namespace PlayClubVR
9 | {
10 | public class TransientHead : ProtectedBehaviour
11 | {
12 | private List rendererList = new List();
13 | private bool hidden = false;
14 | private Transform root;
15 |
16 | private Renderer[] m_tongues;
17 | private Human avatar;
18 | private Transform headTransform;
19 | private Transform eyesTransform;
20 |
21 | public bool Visible
22 | {
23 | get
24 | {
25 | return !hidden;
26 | }
27 | set
28 | {
29 | if (value)
30 | {
31 | Console.WriteLine("SHOW");
32 | }
33 | else
34 | {
35 | Console.WriteLine("HIDE");
36 | }
37 | SetVisibility(value);
38 | }
39 | }
40 |
41 | protected override void OnStart()
42 | {
43 |
44 | avatar = GetComponent();
45 | headTransform = GetHead(avatar);
46 | eyesTransform = GetEyes(avatar);
47 |
48 | root = headTransform.GetComponentsInParent().Last(t => t.name.Contains("body")).parent;
49 | m_tongues = root.GetComponentsInChildren().Where(renderer => renderer.name.StartsWith("cm_O_tang") || renderer.name == "cf_O_tang").Where(tongue => tongue.enabled).ToArray();
50 |
51 | }
52 | public static Transform GetHead(Human human)
53 | {
54 | return human.headPos.GetComponentsInParent().First(t => t.name.StartsWith("c") && t.name.Contains("J_Head"));
55 | }
56 |
57 |
58 | public static Transform GetEyes(Human human)
59 | {
60 | var eyes = human.headPos.GetComponentsInChildren().FirstOrDefault(t => t.name.StartsWith("c") && t.name.EndsWith("Eye_ty"));
61 | if (!eyes)
62 | {
63 | eyes = new GameObject("cm_Eye_ty").transform;
64 | eyes.SetParent(GetHead(human), false);
65 | eyes.transform.localPosition = new Vector3(0, 0.17f, 0.05f);
66 | }
67 | return eyes;
68 | }
69 |
70 | void SetVisibility(bool visible)
71 | {
72 | if (visible)
73 | {
74 | if (hidden)
75 | {
76 | // enable
77 | //Console.WriteLine("Enabling {0} renderers", rendererList.Count);
78 | foreach (var renderer in rendererList)
79 | {
80 | renderer.enabled = true;
81 | }
82 | foreach (var renderer in m_tongues)
83 | {
84 | renderer.enabled = true;
85 | }
86 |
87 | }
88 | }
89 | else
90 | {
91 | if (!hidden)
92 | {
93 | m_tongues = root.GetComponentsInChildren().Where(renderer => renderer.name.StartsWith("cm_O_tang") || renderer.name == "cf_O_tang").Where(tongue => tongue.enabled).ToArray();
94 |
95 | // disable
96 | rendererList.Clear();
97 | foreach (var renderer in headTransform.GetComponentsInChildren().Where(renderer => renderer.enabled))
98 | {
99 | rendererList.Add(renderer);
100 | renderer.enabled = false;
101 | }
102 |
103 | foreach (var renderer in m_tongues)
104 | {
105 | renderer.enabled = false;
106 | }
107 | }
108 | }
109 |
110 | hidden = !visible;
111 | }
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/GamePadClub/Handlers/GameControlHandler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using UnityEngine;
6 | using UnityEngine.EventSystems;
7 | using UnityEngine.UI;
8 | using XInputDotNetPure;
9 |
10 | namespace GamePadClub.Handlers
11 | {
12 | public class GameControlHandler : MonoBehaviour
13 | {
14 | GameControl _GC;
15 | H_Scene _Scene;
16 |
17 | void OnLevelWasLoaded()
18 | {
19 | _GC = FindObjectOfType();
20 | _Scene = FindObjectOfType();
21 | }
22 |
23 | void OnEnable()
24 | {
25 | GamePadController.Instance.Register(HandleInput);
26 | }
27 |
28 | void OnDisable()
29 | {
30 | GamePadController.Instance.Unregister(HandleInput);
31 | }
32 |
33 | bool HandleInput(GamePadState now, GamePadState before)
34 | {
35 | if (GamePadHelper.IsShoulderPressed(now)) return false;
36 |
37 | if (_GC && _Scene && now.Buttons.LeftShoulder == ButtonState.Released && now.Buttons.RightShoulder == ButtonState.Released)
38 | {
39 | return HandleGUI(now, before) || HandleSekkusu(now, before);
40 | }
41 | return false;
42 | }
43 |
44 | bool HandleGUI(GamePadState now, GamePadState before)
45 | {
46 |
47 | if (GamePadHelper.IsPressUp(now.Buttons.Start, before.Buttons.Start))
48 | {
49 | _GC.IsHideUI = !_GC.IsHideUI;
50 | }
51 | return false;
52 | }
53 |
54 | bool HandleSekkusu(GamePadState now, GamePadState before)
55 | {
56 |
57 | // Speed
58 | if (GamePadHelper.IsPressUp(now.DPad.Up, before.DPad.Up))
59 | {
60 | _Scene.Pad.ChangeSpeed(Mathf.Clamp(_Scene.Pad.speed + 0.6f, _Scene.Pad.SpeedMin, _Scene.Pad.SpeedMax));
61 | }
62 | else if(GamePadHelper.IsPressUp(now.DPad.Down, before.DPad.Down))
63 | {
64 | _Scene.Pad.ChangeSpeed(Mathf.Clamp(_Scene.Pad.speed - 0.6f, _Scene.Pad.SpeedMin, _Scene.Pad.SpeedMax));
65 | }
66 |
67 | // Pose
68 | if (GamePadHelper.IsPressUp(now.DPad.Left, before.DPad.Left))
69 | {
70 | ChangePose(-1);
71 | }
72 | else if (GamePadHelper.IsPressUp(now.DPad.Right, before.DPad.Right))
73 | {
74 | ChangePose(1);
75 | }
76 |
77 | // Mode
78 | if (GamePadHelper.IsPressUp(now.Buttons.X, before.Buttons.X))
79 | {
80 | ToggleGrind();
81 | }
82 | if (GamePadHelper.IsPressUp(now.Buttons.Y, before.Buttons.Y))
83 | {
84 | TogglePiston();
85 | }
86 |
87 | // Ejaculation
88 | if (GamePadHelper.IsPressDown(now.Buttons.RightStick, before.Buttons.RightStick))
89 | {
90 | Ejaculate(false);
91 | }
92 |
93 | if (GamePadHelper.IsPressDown(now.Buttons.LeftStick, before.Buttons.LeftStick))
94 | {
95 | Ejaculate(true);
96 | }
97 |
98 |
99 | return false;
100 | }
101 |
102 |
103 |
104 | private void ToggleOrgasmLock()
105 | {
106 | //Console.WriteLine(!_Scene.FemaleGage.Lock ? "Lock" : "Unlock");
107 | // This also updates the GUI!
108 | GameObject.Find("XtcLock").GetComponent().isOn = !_Scene.FemaleGage.Lock;
109 | //_Scene.FemaleGage.ChangeLock(!_Scene.FemaleGage.Lock);
110 | }
111 |
112 |
113 | private void TogglePiston()
114 | {
115 | _Scene.Pad.pistonToggle.OnPointerClick(new PointerEventData(EventSystem.current));
116 |
117 | }
118 |
119 | private void ToggleGrind()
120 | {
121 | _Scene.Pad.grindToggle.OnPointerClick(new PointerEventData(EventSystem.current));
122 | }
123 |
124 | private void SetSpeed(float val)
125 | {
126 | _Scene.Pad.ChangeSpeed(val * 5);
127 | }
128 |
129 | private void Ejaculate(bool outside)
130 | {
131 | if (_Scene.FemaleGage.IsHigh())
132 | {
133 | _Scene.StateMgr.SetXtc(H_Pad.XTC.SYNC);
134 | }
135 | else if (_Scene.Members[0].sex == Human.SEX.MALE)
136 | {
137 | if (outside)
138 | {
139 | _Scene.StateMgr.SetXtc(H_Pad.XTC.M_OUT);
140 | } else
141 | {
142 | _Scene.StateMgr.SetXtc(H_Pad.XTC.M_IN);
143 | }
144 | }
145 | else
146 | {
147 | _Scene.StateMgr.SetXtc(H_Pad.XTC.F);
148 | }
149 | }
150 |
151 | private void ChangePose(int direction)
152 | {
153 | int currentIndex = _Scene.StyleMgr.StyleList.IndexOf(_Scene.StyleMgr.nowStyle);
154 | int nextIndex = ((currentIndex + _Scene.StyleMgr.StyleList.Count) + direction) % _Scene.StyleMgr.StyleList.Count;
155 |
156 | _Scene.ChangeStyle(_Scene.StyleMgr.StyleList[nextIndex].file);
157 | }
158 |
159 | }
160 |
161 |
162 | }
163 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | bld/
21 | [Bb]in/
22 | [Oo]bj/
23 | [Ll]og/
24 |
25 | # Visual Studio 2015 cache/options directory
26 | .vs/
27 | # Uncomment if you have tasks that create the project's static files in wwwroot
28 | #wwwroot/
29 |
30 | # MSTest test Results
31 | [Tt]est[Rr]esult*/
32 | [Bb]uild[Ll]og.*
33 |
34 | # NUNIT
35 | *.VisualState.xml
36 | TestResult.xml
37 |
38 | # Build Results of an ATL Project
39 | [Dd]ebugPS/
40 | [Rr]eleasePS/
41 | dlldata.c
42 |
43 | # DNX
44 | project.lock.json
45 | artifacts/
46 |
47 | *_i.c
48 | *_p.c
49 | *_i.h
50 | *.ilk
51 | *.meta
52 | *.obj
53 | *.pch
54 | *.pdb
55 | *.pgc
56 | *.pgd
57 | *.rsp
58 | *.sbr
59 | *.tlb
60 | *.tli
61 | *.tlh
62 | *.tmp
63 | *.tmp_proj
64 | *.log
65 | *.vspscc
66 | *.vssscc
67 | .builds
68 | *.pidb
69 | *.svclog
70 | *.scc
71 |
72 | # Chutzpah Test files
73 | _Chutzpah*
74 |
75 | # Visual C++ cache files
76 | ipch/
77 | *.aps
78 | *.ncb
79 | *.opendb
80 | *.opensdf
81 | *.sdf
82 | *.cachefile
83 | *.VC.db
84 | *.VC.VC.opendb
85 |
86 | # Visual Studio profiler
87 | *.psess
88 | *.vsp
89 | *.vspx
90 | *.sap
91 |
92 | # TFS 2012 Local Workspace
93 | $tf/
94 |
95 | # Guidance Automation Toolkit
96 | *.gpState
97 |
98 | # ReSharper is a .NET coding add-in
99 | _ReSharper*/
100 | *.[Rr]e[Ss]harper
101 | *.DotSettings.user
102 |
103 | # JustCode is a .NET coding add-in
104 | .JustCode
105 |
106 | # TeamCity is a build add-in
107 | _TeamCity*
108 |
109 | # DotCover is a Code Coverage Tool
110 | *.dotCover
111 |
112 | # NCrunch
113 | _NCrunch_*
114 | .*crunch*.local.xml
115 | nCrunchTemp_*
116 |
117 | # MightyMoose
118 | *.mm.*
119 | AutoTest.Net/
120 |
121 | # Web workbench (sass)
122 | .sass-cache/
123 |
124 | # Installshield output folder
125 | [Ee]xpress/
126 |
127 | # DocProject is a documentation generator add-in
128 | DocProject/buildhelp/
129 | DocProject/Help/*.HxT
130 | DocProject/Help/*.HxC
131 | DocProject/Help/*.hhc
132 | DocProject/Help/*.hhk
133 | DocProject/Help/*.hhp
134 | DocProject/Help/Html2
135 | DocProject/Help/html
136 |
137 | # Click-Once directory
138 | publish/
139 |
140 | # Publish Web Output
141 | *.[Pp]ublish.xml
142 | *.azurePubxml
143 | # TODO: Comment the next line if you want to checkin your web deploy settings
144 | # but database connection strings (with potential passwords) will be unencrypted
145 | *.pubxml
146 | *.publishproj
147 |
148 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
149 | # checkin your Azure Web App publish settings, but sensitive information contained
150 | # in these scripts will be unencrypted
151 | PublishScripts/
152 |
153 | # NuGet Packages
154 | *.nupkg
155 | # The packages folder can be ignored because of Package Restore
156 | **/packages/*
157 | # except build/, which is used as an MSBuild target.
158 | !**/packages/build/
159 | # Uncomment if necessary however generally it will be regenerated when needed
160 | #!**/packages/repositories.config
161 | # NuGet v3's project.json files produces more ignoreable files
162 | *.nuget.props
163 | *.nuget.targets
164 |
165 | # Microsoft Azure Build Output
166 | csx/
167 | *.build.csdef
168 |
169 | # Microsoft Azure Emulator
170 | ecf/
171 | rcf/
172 |
173 | # Windows Store app package directories and files
174 | AppPackages/
175 | BundleArtifacts/
176 | Package.StoreAssociation.xml
177 | _pkginfo.txt
178 |
179 | # Visual Studio cache files
180 | # files ending in .cache can be ignored
181 | *.[Cc]ache
182 | # but keep track of directories ending in .cache
183 | !*.[Cc]ache/
184 |
185 | # Others
186 | ClientBin/
187 | ~$*
188 | *~
189 | *.dbmdl
190 | *.dbproj.schemaview
191 | *.pfx
192 | *.publishsettings
193 | node_modules/
194 | orleans.codegen.cs
195 |
196 | # Since there are multiple workflows, uncomment next line to ignore bower_components
197 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
198 | #bower_components/
199 |
200 | # RIA/Silverlight projects
201 | Generated_Code/
202 |
203 | # Backup & report files from converting an old project file
204 | # to a newer Visual Studio version. Backup files are not needed,
205 | # because we have git ;-)
206 | _UpgradeReport_Files/
207 | Backup*/
208 | UpgradeLog*.XML
209 | UpgradeLog*.htm
210 |
211 | # SQL Server files
212 | *.mdf
213 | *.ldf
214 |
215 | # Business Intelligence projects
216 | *.rdl.data
217 | *.bim.layout
218 | *.bim_*.settings
219 |
220 | # Microsoft Fakes
221 | FakesAssemblies/
222 |
223 | # GhostDoc plugin setting file
224 | *.GhostDoc.xml
225 |
226 | # Node.js Tools for Visual Studio
227 | .ntvs_analysis.dat
228 |
229 | # Visual Studio 6 build log
230 | *.plg
231 |
232 | # Visual Studio 6 workspace options file
233 | *.opt
234 |
235 | # Visual Studio LightSwitch build output
236 | **/*.HTMLClient/GeneratedArtifacts
237 | **/*.DesktopClient/GeneratedArtifacts
238 | **/*.DesktopClient/ModelManifest.xml
239 | **/*.Server/GeneratedArtifacts
240 | **/*.Server/ModelManifest.xml
241 | _Pvt_Extensions
242 |
243 | # Paket dependency manager
244 | .paket/paket.exe
245 | paket-files/
246 |
247 | # FAKE - F# Make
248 | .fake/
249 |
250 | # JetBrains Rider
251 | .idea/
252 | *.sln.iml
--------------------------------------------------------------------------------
/PlayClubVR/DynamicColliderRegistry.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using UnityEngine;
6 | using VRGIN.Core;
7 | using VRGIN.Helpers;
8 |
9 | namespace PlayClubVR
10 | {
11 |
12 | public static class DynamicColliderRegistry
13 | {
14 | private static IDictionary> _Colliders = new Dictionary>();
15 | private static IList _Bones = new List();
16 |
17 | public static IEnumerable Bones { get { return _Bones; } }
18 |
19 | public static void RegisterCollider(DynamicBoneCollider collider, Predicate targetSelector = null)
20 | {
21 | if (targetSelector == null) targetSelector = (bone) => true;
22 |
23 | _Colliders[collider] = targetSelector;
24 |
25 | foreach (var bone in _Bones)
26 | {
27 | Correlate(bone, collider, targetSelector);
28 | }
29 | }
30 |
31 | private static void Correlate(IDynamicBoneWrapper bone, DynamicBoneCollider collider, Predicate targetSelector)
32 | {
33 | if (targetSelector(bone))
34 | {
35 | if (!bone.Colliders.Contains(collider))
36 | {
37 | bone.Colliders.Add(collider);
38 | }
39 | }
40 | else
41 | {
42 | bone.Colliders.Remove(collider);
43 | }
44 | }
45 |
46 | private static void Register(IDynamicBoneWrapper wrapper)
47 | {
48 | _Bones.Add(wrapper);
49 |
50 | foreach(var colliderPair in _Colliders)
51 | {
52 | Correlate(wrapper, colliderPair.Key, colliderPair.Value);
53 | }
54 | }
55 |
56 | public static void RegisterDynamicBone(DynamicBone bone)
57 | {
58 | Register(new DynamicBoneWrapper(bone));
59 | }
60 |
61 | public static void RegisterDynamicBone(DynamicBone_Custom bone)
62 | {
63 | Register(new DynamicBone_CustomWrapper(bone));
64 | }
65 |
66 | public static void Clear()
67 | {
68 | _Colliders.Clear();
69 | _Bones.Clear();
70 | }
71 |
72 | public static Predicate GetCondition(DynamicBoneCollider key)
73 | {
74 | return _Colliders[key];
75 | }
76 | }
77 |
78 |
79 | public interface IDynamicBoneWrapper
80 | {
81 | MonoBehaviour Bone
82 | {
83 | get;
84 | }
85 |
86 | Transform Root
87 | {
88 | get;
89 | }
90 |
91 | Transform Rim
92 | {
93 | get;
94 | }
95 |
96 | IEnumerable Nodes { get; }
97 |
98 |
99 | List Colliders { get; }
100 | }
101 |
102 | public class DynamicBoneWrapper : IDynamicBoneWrapper
103 | {
104 | public MonoBehaviour Bone
105 | {
106 | get;
107 | private set;
108 | }
109 |
110 | public List Colliders
111 | {
112 | get
113 | {
114 | return (Bone as DynamicBone).m_Colliders;
115 | }
116 | }
117 |
118 | public Transform Root
119 | {
120 | get
121 | {
122 | return (Bone as DynamicBone).m_Root;
123 | }
124 | }
125 |
126 | public Transform Rim
127 | {
128 | get
129 | {
130 | return (Bone as DynamicBone).m_Root.gameObject.Descendants().Last().transform;
131 | }
132 | }
133 |
134 | public IEnumerable Nodes
135 | {
136 | get
137 | {
138 | return Root.gameObject.Descendants().Select(d => d.transform).Concat(new Transform[] { Root });
139 | }
140 | }
141 |
142 | public DynamicBoneWrapper(DynamicBone bone)
143 | {
144 | Bone = bone;
145 | }
146 | }
147 |
148 | public class DynamicBone_CustomWrapper : IDynamicBoneWrapper
149 | {
150 | public MonoBehaviour Bone
151 | {
152 | get;
153 | private set;
154 | }
155 |
156 | public List Colliders
157 | {
158 | get
159 | {
160 | return (Bone as DynamicBone_Custom).m_Colliders;
161 | }
162 | }
163 |
164 | public Transform Root
165 | {
166 | get
167 | {
168 | return (Bone as DynamicBone_Custom).m_Nodes[0];
169 | }
170 | }
171 |
172 | public Transform Rim
173 | {
174 | get
175 | {
176 | return (Bone as DynamicBone_Custom).m_Nodes.Last();
177 | }
178 | }
179 |
180 | public IEnumerable Nodes
181 | {
182 | get
183 | {
184 | return(Bone as DynamicBone_Custom).m_Nodes;
185 | }
186 | }
187 |
188 | public DynamicBone_CustomWrapper(DynamicBone_Custom bone)
189 | {
190 | Bone = bone;
191 | }
192 | }
193 | }
194 |
--------------------------------------------------------------------------------
/PlayClubVR/MaestroTool.cs:
--------------------------------------------------------------------------------
1 | using IllusionPlugin;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Diagnostics;
5 | using System.Linq;
6 | using System.Runtime.InteropServices;
7 | using System.Text;
8 | using UnityEngine;
9 | using Valve.VR;
10 | using VRGIN.Core;
11 | using VRGIN.Controls;
12 | using VRGIN.Helpers;
13 | using VRGIN.Native;
14 | using VRGIN.Controls.Tools;
15 | using IllusionInjector;
16 | using MaestroMode;
17 |
18 | namespace PlayClubVR
19 | {
20 | public class MaestroTool : Tool
21 | {
22 | // This is to avoid a dependency to MaestroMode (no instance variables allowed or the application will crash at the absence of the DLL)
23 | object __Handle = null;
24 | private IKHandle _Handle
25 | {
26 | get
27 | {
28 | return __Handle as IKHandle;
29 | }
30 | set
31 | {
32 | __Handle = value;
33 | }
34 | }
35 | Controller _Controller;
36 | Transform _Dummy = null;
37 | private bool _Dragging;
38 | private bool _Focused;
39 | private int _FocusCount;
40 |
41 | private static bool? _Available;
42 |
43 | public override Texture2D Image
44 | {
45 | get
46 | {
47 | return UnityHelper.LoadImage("icon_maestro.png");
48 | }
49 | }
50 |
51 | ///
52 | /// Gets whether or not the MaestroMode DLL is loaded.
53 | ///
54 | public static bool IsAvailable
55 | {
56 | get
57 | {
58 | return PluginManager.Plugins.Any(plugin => plugin.GetType().FullName == "MaestroMode.MaestroPlugin");
59 | }
60 | }
61 |
62 | public MaestroPlugin Maestro
63 | {
64 | get
65 | {
66 | return PluginManager.Plugins.OfType().FirstOrDefault();
67 | }
68 | }
69 |
70 | protected override void OnStart()
71 | {
72 | base.OnStart();
73 |
74 | _Controller = GetComponent();
75 | _Dummy = new GameObject().transform;
76 | _Dummy.SetParent(transform, false);
77 | }
78 |
79 | protected override void OnDisable()
80 | {
81 | base.OnDisable();
82 | _FocusCount = 0;
83 | }
84 |
85 | protected override void OnFixedUpdate()
86 | {
87 | base.OnFixedUpdate();
88 |
89 | if (_Controller.Tracking.isValid)
90 | {
91 | var device = SteamVR_Controller.Input((int)_Controller.Tracking.index);
92 |
93 | if (device.GetPressDown(EVRButtonId.k_EButton_SteamVR_Trigger))
94 | {
95 | if(_FocusCount == 0)
96 | {
97 | VRLog.Info("Search for handle");
98 | _Handle = FindNextHandle();
99 | }
100 | if (_Handle)
101 | {
102 | _Handle.gameObject.SendMessage("Select");
103 | _Handle.gameObject.SendMessage("Activate", 1);
104 |
105 | _Handle.MarkDirty();
106 |
107 | _Dummy.position = _Handle.transform.position;
108 | _Dummy.rotation = _Handle.transform.rotation;
109 | _Dragging = true;
110 | }
111 | }
112 | if (_Handle && _Dragging)
113 | {
114 | if (device.GetPress(EVRButtonId.k_EButton_SteamVR_Trigger))
115 | {
116 | _Handle.transform.position = _Dummy.position;
117 | _Handle.transform.rotation = _Dummy.rotation;
118 | }
119 | if (device.GetPressUp(EVRButtonId.k_EButton_SteamVR_Trigger))
120 | {
121 | _Handle.gameObject.SendMessage("Deselect");
122 | _Dragging = false;
123 | }
124 | }
125 |
126 | if(_Handle && device.GetPressDown(EVRButtonId.k_EButton_SteamVR_Touchpad))
127 | {
128 | _Handle.gameObject.SendMessage("Reset");
129 | }
130 |
131 | if(device.GetPressDown(EVRButtonId.k_EButton_Grip))
132 | {
133 | // Toggle
134 | var prevMode = Maestro.Mode;
135 | Maestro.Mode = MaestroPlugin.MaestroMode.FBBIK;
136 | Maestro.Visible = prevMode == Maestro.Mode ? !Maestro.Visible : true;
137 | }
138 | }
139 | }
140 |
141 | public override List GetHelpTexts()
142 | {
143 | return base.GetHelpTexts();
144 | }
145 |
146 | private IKHandle FindNextHandle()
147 | {
148 | var handle = Maestro.Handles.OrderBy(h => Vector3.Distance(_Controller.transform.position, h.transform.position)).FirstOrDefault();
149 |
150 | if(handle && Vector3.Distance(_Controller.transform.position, handle.transform.position) < 0.5f)
151 | {
152 | return handle;
153 | } else
154 | {
155 | return null;
156 | }
157 |
158 | }
159 |
160 | protected override void OnDestroy()
161 | {
162 | }
163 | }
164 | }
165 |
--------------------------------------------------------------------------------
/PlayClubStudioVR/PlayClubStudioVR.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {9F6E1BC0-2C48-433E-A8C7-5C21DB635C99}
8 | Library
9 | Properties
10 | PlayClubStudioVR
11 | PlayClubStudioVR
12 | v3.5
13 | 512
14 |
15 |
16 | true
17 | full
18 | false
19 | bin\Debug\
20 | DEBUG;TRACE
21 | prompt
22 | 4
23 |
24 |
25 | pdbonly
26 | true
27 | bin\Release\
28 | TRACE
29 | prompt
30 | 4
31 |
32 |
33 | bin\Install\
34 | TRACE;DEBUG
35 | true
36 | pdbonly
37 | AnyCPU
38 | prompt
39 | MinimumRecommendedRules.ruleset
40 | 0
41 |
42 |
43 |
44 | ..\Libs\Assembly-CSharp_Studio.dll
45 | False
46 |
47 |
48 | ..\Libs\Injector\IllusionPlugin.dll
49 | False
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | ..\VRGIN\Libs\Unity 4.6\UnityEngine.dll
59 | False
60 |
61 |
62 | ..\VRGIN\Libs\Unity 4.6\UnityEngine.UI.dll
63 | False
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 | {be0fd119-262b-42c0-be1f-8bce0af022d8}
79 | PlayClubVR
80 |
81 |
82 | {8fe87229-42a4-4cb0-846a-7a2726569b17}
83 | VRGIN.U46
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
100 |
101 |
102 |
103 | $(registry:HKEY_CURRENT_USER\Software\illusion\PlayClub@INSTALLDIR)
104 | $(InstallDir)Plugins\
105 | $(InstallDir)PlayClubStudio_Data\
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
--------------------------------------------------------------------------------
/PlayClubVR/PlayClubStandingMode.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using UnityEngine;
6 | using VRGIN.Core;
7 | using VRGIN.Controls;
8 | using VRGIN.Helpers;
9 | using VRGIN.Modes;
10 | using VRGIN.Controls.Speech;
11 | using Leap.Unity;
12 |
13 | namespace PlayClubVR
14 | {
15 | public class PlayClubStandingMode : StandingMode
16 | {
17 | private IllusionCamera _IllusionCamera;
18 |
19 | protected virtual void OnEnable()
20 | {
21 | base.OnEnable();
22 | Logger.Info("Enter standing mode");
23 |
24 | }
25 |
26 | protected virtual void OnDisable()
27 | {
28 | base.OnDisable();
29 | Logger.Info("Leave standing mode");
30 | }
31 |
32 | public override void OnDestroy()
33 | {
34 | base.OnDestroy();
35 |
36 | DynamicColliderRegistry.Clear();
37 | }
38 |
39 | protected override void OnStart()
40 | {
41 | base.OnStart();
42 | _IllusionCamera = FindObjectOfType();
43 | gameObject.AddComponent();
44 | }
45 |
46 | protected override void OnLevel(int level)
47 | {
48 | base.OnLevel(level);
49 | _IllusionCamera = FindObjectOfType();
50 |
51 | }
52 |
53 | public override IEnumerable Tools
54 | {
55 | get
56 | {
57 | var tools = base.Tools.Concat(new Type[] { typeof(PlayTool) });
58 | if (MaestroTool.IsAvailable) {
59 | tools = tools.Concat(new Type[] { typeof(MaestroTool) });
60 | }
61 | return tools;
62 | }
63 | }
64 |
65 | protected override IEnumerable CreateShortcuts()
66 | {
67 | var interpreter = VR.Interpreter as PlayClubInterpreter;
68 |
69 | return base.CreateShortcuts().Concat(new IShortcut[] {
70 | new MultiKeyboardShortcut(new KeyStroke("Ctrl + C"), new KeyStroke("Ctrl + C"), ChangeMode ),
71 |
72 | new VoiceShortcut(PlayClubVoiceCommand.StartAnimation, delegate { interpreter.TogglePiston(true); }),
73 | new VoiceShortcut(PlayClubVoiceCommand.StopAnimation, delegate { interpreter.TogglePiston(false); }),
74 | new VoiceShortcut(PlayClubVoiceCommand.Faster, delegate { interpreter.IncreaseSpeed(0.6f); }),
75 | new VoiceShortcut(PlayClubVoiceCommand.Slower, delegate { interpreter.IncreaseSpeed(-0.6f); }),
76 | new VoiceShortcut(PlayClubVoiceCommand.Climax, delegate { interpreter.Ejaculate(); }),
77 | new VoiceShortcut(PlayClubVoiceCommand.NextAnimation, delegate { interpreter.ChangePose(1); }),
78 | new VoiceShortcut(PlayClubVoiceCommand.PreviousAnimation, delegate { interpreter.ChangePose(-1); }),
79 | new VoiceShortcut(PlayClubVoiceCommand.DisableClimax, delegate { interpreter.ToggleOrgasmLock(true); }),
80 | new VoiceShortcut(PlayClubVoiceCommand.EnableClimax, delegate { interpreter.ToggleOrgasmLock(false); }),
81 | });
82 | }
83 |
84 | protected virtual void ChangeMode()
85 | {
86 | VR.Manager.SetMode();
87 | }
88 |
89 | protected override void CreateControllers()
90 | {
91 | base.CreateControllers();
92 |
93 | foreach (var controller in new Controller[] { Left, Right })
94 | {
95 | var boneCollider = CreateCollider(controller.transform, -0.05f);
96 | boneCollider.m_Center.y = -0.03f;
97 | boneCollider.m_Center.z = 0.01f;
98 | DynamicColliderRegistry.RegisterCollider(boneCollider, (b) => !IsNotBust(b));
99 |
100 | boneCollider = CreateCollider(controller.transform, 0.01f);
101 | boneCollider.m_Center.y = -0.03f;
102 | boneCollider.m_Center.z = 0.01f;
103 | DynamicColliderRegistry.RegisterCollider(boneCollider, IsNotBust);
104 | }
105 | }
106 |
107 | private DynamicBoneCollider CreateCollider(Transform parent, float radius)
108 | {
109 | var collider = UnityHelper.CreateGameObjectAsChild("Dynamic Collider", parent).gameObject.AddComponent();
110 | collider.m_Radius = radius;
111 | collider.m_Bound = DynamicBoneCollider.Bound.Outside;
112 | collider.m_Direction = DynamicBoneCollider.Direction.X;
113 | collider.m_Center.y = 0;
114 | collider.m_Center.z = 0;
115 | return collider;
116 | }
117 |
118 | protected override HandAttachments BuildAttachmentHand(Chirality handedness)
119 | {
120 | var hand = base.BuildAttachmentHand(handedness);
121 |
122 | foreach (var sphere in new Transform[] { hand.Thumb, hand.Index, hand.Middle, hand.Ring, hand.Pinky, hand.Palm })
123 | {
124 | var boneCollider = CreateCollider(sphere, -0.05f);
125 | boneCollider.enabled = false;
126 | DynamicColliderRegistry.RegisterCollider(boneCollider, (b) => !IsNotBust(b));
127 |
128 | boneCollider = CreateCollider(sphere, 0.01f);
129 | boneCollider.enabled = false;
130 | DynamicColliderRegistry.RegisterCollider(boneCollider, IsNotBust);
131 |
132 |
133 | }
134 | hand.OnBegin += delegate
135 | {
136 | foreach(var collider in hand.GetComponentsInChildren())
137 | {
138 | collider.enabled = true;
139 | }
140 | };
141 |
142 | hand.OnFinish += delegate
143 | {
144 | foreach (var collider in hand.GetComponentsInChildren())
145 | {
146 | collider.enabled = false;
147 | }
148 | };
149 |
150 | return hand;
151 | }
152 |
153 | private bool IsNotBust(IDynamicBoneWrapper wrapper)
154 | {
155 | return !wrapper.Bone.name.Contains("Bust");
156 | }
157 |
158 | protected override void SyncCameras()
159 | {
160 | base.SyncCameras();
161 | if (_IllusionCamera)
162 | {
163 | var my = VR.Camera.SteamCam.head;
164 |
165 | _IllusionCamera.Set(
166 | my.position + my.forward,
167 | Quaternion.LookRotation(my.forward, my.up).eulerAngles,
168 | 1);
169 | }
170 | }
171 | //protected override Controller CreateLeftController()
172 | //{
173 | // return PlayClubController.Create();
174 | //}
175 |
176 | //protected override Controller CreateRightController()
177 | //{
178 | // var controller = PlayClubController.Create();
179 | // controller.ToolIndex = 1;
180 | // return controller;
181 | //}
182 | }
183 | }
184 |
--------------------------------------------------------------------------------
/PlayClubVR/PlayClubVR.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {BE0FD119-262B-42C0-BE1F-8BCE0AF022D8}
8 | Library
9 | Properties
10 | PlayClubVR
11 | PlayClubVR
12 | v3.5
13 | 512
14 |
15 |
16 | true
17 | full
18 | false
19 | bin\Debug\
20 | DEBUG;TRACE
21 | prompt
22 | 4
23 |
24 |
25 | pdbonly
26 | true
27 | bin\Release\
28 | TRACE
29 | prompt
30 | 4
31 |
32 |
33 | bin\Install\
34 | TRACE;DEBUG
35 | true
36 | pdbonly
37 | AnyCPU
38 | prompt
39 | MinimumRecommendedRules.ruleset
40 | 0
41 |
42 |
43 |
44 | ..\Libs\Assembly-CSharp.dll
45 | False
46 |
47 |
48 | ..\Libs\CameraModifications.dll
49 |
50 |
51 | ..\Libs\Injector\IllusionInjector.dll
52 |
53 |
54 | ..\Libs\Injector\IllusionPlugin.dll
55 | False
56 |
57 |
58 | False
59 | ..\VRGIN\Libs\LeapCSharp.NET3.5.dll
60 |
61 |
62 | ..\Libs\MaestroMode.dll
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 | ..\VRGIN\Libs\Unity 4.6\UnityEngine.dll
72 | False
73 |
74 |
75 | ..\VRGIN\Libs\Unity 4.6\UnityEngine.UI.dll
76 | False
77 |
78 |
79 | False
80 | ..\VRGIN\Libs\WindowsInput.dll
81 |
82 |
83 | ..\Libs\XInputDotNetPure.dll
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 | Always
108 |
109 |
110 |
111 |
112 | {8cf2e8ae-b1ca-4b00-b997-74622bdaf627}
113 | GamePadClub
114 |
115 |
116 | {8fe87229-42a4-4cb0-846a-7a2726569b17}
117 | VRGIN.U46
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
134 |
135 |
136 |
137 | $(registry:HKEY_CURRENT_USER\Software\illusion\PlayClub@INSTALLDIR)
138 | $(InstallDir)Plugins\
139 | $(InstallDir)PlayClub_Data\
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
--------------------------------------------------------------------------------
/PlayClubVR/PlayClubInterpreter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using UnityEngine;
6 | using UnityEngine.EventSystems;
7 | using UnityEngine.UI;
8 | using VRGIN.Core;
9 |
10 | namespace PlayClubVR
11 | {
12 | public class PlayClubInterpreter : GameInterpreter
13 | {
14 | ///
15 | /// Gets the current H scene.
16 | ///
17 | public H_Scene Scene { get; private set; }
18 |
19 | private readonly int pngLayer = LayerMask.NameToLayer("PNG");
20 | private List _Actors = new List();
21 | public override IEnumerable Actors
22 | {
23 | get { return _Actors; }
24 | }
25 |
26 | protected override void OnStart()
27 | {
28 | base.OnStart();
29 |
30 | gameObject.AddComponent();
31 | gameObject.AddComponent();
32 |
33 | LookForScene();
34 |
35 | if (IsUIOnlyScene)
36 | {
37 | GameControl ctrl = GameObject.FindObjectOfType();
38 | ctrl.MapDataCtrl.ChangeMap(ctrl.MapDataCtrl.Datas.ElementAt(1).Value, ctrl, VRCamera.Instance.camera, false, false);
39 | }
40 |
41 | }
42 |
43 | public override bool IsIgnoredCanvas(Canvas canvas)
44 | {
45 | return canvas.gameObject.layer == pngLayer;
46 | }
47 |
48 |
49 | protected override void OnLevel(int level)
50 | {
51 | base.OnLevel(level);
52 |
53 | LookForScene();
54 |
55 | if(IsUIOnlyScene)
56 | {
57 | GameControl ctrl = GameObject.FindObjectOfType();
58 | ctrl.MapDataCtrl.ChangeMap(ctrl.MapDataCtrl.Datas.ElementAt(1).Value, ctrl, VRCamera.Instance.camera, false, false);
59 | }
60 |
61 | //var oldShadowCaster = VR.Camera.SteamCam.head.FindChild("ShadowCaster");
62 | //if (oldShadowCaster)
63 | //{
64 | // DestroyImmediate(oldShadowCaster);
65 | //}
66 | //var shadowCaster = GameObject.Find("ShadowCaster");
67 | //if(shadowCaster)
68 | //{
69 | // VRLog.Info("FOund shadow caster");
70 | // //shadowCaster.transform.SetParent(VR.Camera.SteamCam.head);
71 | // shadowCaster.transform.GetChild(0).gameObject.AddComponent();
72 | //}
73 | }
74 |
75 | private bool IsUIOnlyScene
76 | {
77 | get
78 | {
79 | return !GameObject.FindObjectOfType();
80 | }
81 | }
82 |
83 | protected override void OnUpdate()
84 | {
85 | base.OnUpdate();
86 |
87 | if (Scene)
88 | {
89 | CleanActors();
90 | } else
91 | {
92 | _Actors.Clear();
93 | }
94 | }
95 |
96 | ///
97 | /// Removes dead entries from actors list and adds new ones.
98 | ///
99 | private void CleanActors()
100 | {
101 | _Actors = Actors.Where(a => a.IsValid).ToList();
102 |
103 | foreach (var member in Scene.Members)
104 | {
105 | AddActor(member);
106 | }
107 | }
108 |
109 | private void AddActor(Human member)
110 | {
111 | if (!member.GetComponent())
112 | {
113 | _Actors.Add(new PlayClubActor(member));
114 | }
115 | }
116 |
117 | ///
118 | /// Looks for the scene object.
119 | ///
120 | private void LookForScene()
121 | {
122 | Scene = GameObject.FindObjectOfType();
123 |
124 | if(!Scene)
125 | {
126 | //// Search for actors
127 | //foreach (var member in GameObject.FindObjectsOfType())
128 | //{
129 | // AddActor(member);
130 | //}
131 | }
132 | }
133 |
134 | public override bool IsBody(Collider collider)
135 | {
136 | return collider.gameObject.layer == LayerMask.NameToLayer("ToLiquidCollision")
137 | && collider.transform.parent.name.StartsWith("cf_") || collider.transform.parent.name.StartsWith("cm_");
138 | }
139 |
140 |
141 | public void ChangePose(int direction)
142 | {
143 | if (!Scene) return;
144 |
145 | int currentIndex = Scene.StyleMgr.StyleList.IndexOf(Scene.StyleMgr.nowStyle);
146 | int nextIndex = ((currentIndex + Scene.StyleMgr.StyleList.Count) + direction) % Scene.StyleMgr.StyleList.Count;
147 |
148 | ChangeStyle(Scene.StyleMgr.StyleList[nextIndex].file);
149 | }
150 |
151 | internal void IncreaseSpeed(float v)
152 | {
153 | Scene.Pad.ChangeSpeed(Mathf.Clamp(Scene.Pad.speed + v, Scene.Pad.SpeedMin, Scene.Pad.SpeedMax));
154 | }
155 |
156 | public void ChangeStyle(string name)
157 | {
158 | if (!Scene) return;
159 |
160 | Scene.ChangeStyle(name);
161 | Scene.StyleToGUI(name);
162 | Scene.CrossFadeStart();
163 | }
164 |
165 | public void Ejaculate()
166 | {
167 | if (!Scene) return;
168 |
169 | if (Scene.FemaleGage.IsHigh())
170 | {
171 | Scene.StateMgr.SetXtc(H_Pad.XTC.SYNC);
172 | }
173 | else if (Scene.Members[0].sex == Human.SEX.MALE)
174 | {
175 | Scene.StateMgr.SetXtc(H_Pad.XTC.M_OUT);
176 | }
177 | else
178 | {
179 | Scene.StateMgr.SetXtc(H_Pad.XTC.F);
180 | }
181 | }
182 |
183 | public void SetSpeed(float val)
184 | {
185 | if (!Scene) return;
186 |
187 | Scene.Pad.ChangeSpeed(val * 5);
188 | }
189 |
190 | public void ToggleOrgasmLock(bool? enabled = null)
191 | {
192 | if (!Scene) return;
193 | //Console.WriteLine(!scene.FemaleGage.Lock ? "Lock" : "Unlock");
194 | // This also updates the GUI!
195 | var toggle = GameObject.Find("XtcLock").GetComponent();
196 |
197 | if (enabled == null || (toggle.isOn != enabled.Value))
198 | toggle.isOn = !Scene.FemaleGage.Lock;
199 | //scene.FemaleGage.ChangeLock(!scene.FemaleGage.Lock);
200 | }
201 |
202 | public void TogglePiston(bool? start = null)
203 | {
204 | if (!Scene) return;
205 |
206 | if (start == null || (Scene.Pad.pistonToggle.isOn != start.Value))
207 | Scene.Pad.pistonToggle.OnPointerClick(new PointerEventData(EventSystem.current));
208 |
209 | }
210 |
211 | public void ToggleGrind(bool? start = null)
212 | {
213 | if (!Scene) return;
214 |
215 | if (start == null || (Scene.Pad.grindToggle.isOn != start.Value))
216 | Scene.Pad.grindToggle.OnPointerClick(new PointerEventData(EventSystem.current));
217 | }
218 |
219 |
220 | }
221 | }
222 |
--------------------------------------------------------------------------------
/PlayClubVR/PlayClubSeatedMode.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Reflection;
5 | using System.Text;
6 | using UnityEngine;
7 | using Valve.VR;
8 | using VRGIN.Core;
9 | using VRGIN.Controls;
10 | using VRGIN.Helpers;
11 | using VRGIN.Modes;
12 | using GamePadClub;
13 | using XInputDotNetPure;
14 | using VRGIN.Controls.Speech;
15 | using Leap.Unity;
16 |
17 | namespace PlayClubVR
18 | {
19 | public class PlayClubSeatedMode : SeatedMode
20 | {
21 | private FieldInfo _IllusionCameraRotation = typeof(IllusionCamera).GetField("rotate", BindingFlags.NonPublic | BindingFlags.Instance);
22 | private IllusionCamera _IllusionCamera;
23 |
24 | protected override void OnEnable()
25 | {
26 | base.OnEnable();
27 | Logger.Info("Enter seated mode");
28 | GamePadController.Instance.Register(HandleInput);
29 |
30 | }
31 | protected override void OnDisable()
32 | {
33 | base.OnDisable();
34 |
35 | Logger.Info("Leave seated mode");
36 | GamePadController.Instance.Unregister(HandleInput);
37 |
38 | }
39 |
40 | public override void OnDestroy()
41 | {
42 | base.OnDestroy();
43 |
44 | DynamicColliderRegistry.Clear();
45 | }
46 | bool HandleInput(GamePadState nowState, GamePadState prevState)
47 | {
48 | if (nowState.Buttons.LeftShoulder == ButtonState.Pressed)
49 | {
50 | if (GamePadHelper.IsPressUp(nowState.Buttons.Start, prevState.Buttons.Start))
51 | {
52 | Recenter();
53 | }
54 |
55 | Vector2 rightStick = new Vector2(nowState.ThumbSticks.Right.X, nowState.ThumbSticks.Right.Y);
56 | Vector2 leftStick = new Vector2(nowState.ThumbSticks.Left.X, nowState.ThumbSticks.Left.Y);
57 | if(rightStick.magnitude > 0.1f)
58 | {
59 | VR.Settings.Rotation += rightStick.x * Time.deltaTime * 50f;
60 | VR.Settings.OffsetY += rightStick.y * Time.deltaTime * 0.1f;
61 |
62 | }
63 | if (leftStick.magnitude > 0.1f)
64 | {
65 | VR.Settings.Distance += leftStick.x * Time.deltaTime * 0.1f;
66 | VR.Settings.Angle += leftStick.y * Time.deltaTime * 50f;
67 | }
68 |
69 | if(nowState.DPad.Up == ButtonState.Pressed)
70 | {
71 | VR.Settings.IPDScale += Time.deltaTime * 0.1f;
72 | } else if(nowState.DPad.Down == ButtonState.Pressed)
73 | {
74 | VR.Settings.IPDScale -= Time.deltaTime * 0.1f;
75 | }
76 |
77 | // Impersonate
78 | if (GamePadHelper.IsPressUp(nowState.Buttons.Y, prevState.Buttons.Y))
79 | {
80 | if (LockTarget == null || !LockTarget.IsValid) {
81 | Impersonate(VR.Interpreter.Actors.FirstOrDefault());
82 | } else {
83 | Impersonate(null);
84 | }
85 | }
86 |
87 | }
88 |
89 | return false;
90 | }
91 |
92 | protected override void CreateControllers()
93 | {
94 | base.CreateControllers();
95 |
96 | foreach (var controller in new Controller[] { Left, Right })
97 | {
98 | var boneCollider = new GameObject("Dynamic Collider").AddComponent();
99 | boneCollider.transform.SetParent(controller.transform, false);
100 | boneCollider.m_Radius = 0.01f; // Does not seem to have an effect
101 | boneCollider.m_Height = 0f;
102 | boneCollider.m_Center.y = 0;
103 | boneCollider.m_Center.z = 0;
104 | boneCollider.m_Center.x = 0;
105 |
106 | boneCollider.m_Bound = DynamicBoneCollider.Bound.Outside;
107 | DynamicColliderRegistry.RegisterCollider(boneCollider);
108 |
109 | }
110 | }
111 |
112 | public override ETrackingUniverseOrigin TrackingOrigin
113 | {
114 | get
115 | {
116 | return ETrackingUniverseOrigin.TrackingUniverseSeated;
117 | }
118 | }
119 |
120 |
121 | public override IEnumerable Tools
122 | {
123 | get
124 | {
125 | var tools = base.Tools;
126 | if (MaestroTool.IsAvailable)
127 | {
128 | tools = tools.Concat(new Type[] { typeof(MaestroTool) });
129 | }
130 | return tools;
131 | }
132 | }
133 |
134 | protected override void ChangeModeOnControllersDetected()
135 | {
136 | ChangeMode();
137 | }
138 |
139 | protected virtual void ChangeMode()
140 | {
141 | VR.Manager.SetMode();
142 | }
143 |
144 | protected override IEnumerable CreateShortcuts()
145 | {
146 | var interpreter = VR.Interpreter as PlayClubInterpreter;
147 |
148 | return base.CreateShortcuts().Concat(new IShortcut[] {
149 | new MultiKeyboardShortcut(new KeyStroke("Ctrl + C"), new KeyStroke("Ctrl + C"), ChangeMode ),
150 |
151 | new VoiceShortcut(PlayClubVoiceCommand.StartAnimation, delegate { interpreter.TogglePiston(true); }),
152 | new VoiceShortcut(PlayClubVoiceCommand.StopAnimation, delegate { interpreter.TogglePiston(false); }),
153 | new VoiceShortcut(PlayClubVoiceCommand.Faster, delegate { interpreter.IncreaseSpeed(0.6f); }),
154 | new VoiceShortcut(PlayClubVoiceCommand.Slower, delegate { interpreter.IncreaseSpeed(-0.6f); }),
155 | new VoiceShortcut(PlayClubVoiceCommand.Climax, delegate { interpreter.Ejaculate(); }),
156 | new VoiceShortcut(PlayClubVoiceCommand.NextAnimation, delegate { interpreter.ChangePose(1); }),
157 | new VoiceShortcut(PlayClubVoiceCommand.PreviousAnimation, delegate { interpreter.ChangePose(-1); }),
158 | new VoiceShortcut(PlayClubVoiceCommand.DisableClimax, delegate { interpreter.ToggleOrgasmLock(true); }),
159 | new VoiceShortcut(PlayClubVoiceCommand.EnableClimax, delegate { interpreter.ToggleOrgasmLock(false); }),
160 |
161 | });
162 | }
163 |
164 | protected override void OnStart()
165 | {
166 | base.OnStart();
167 | _IllusionCamera = FindObjectOfType();
168 |
169 | }
170 |
171 | protected override void OnLevel(int level)
172 | {
173 | base.OnLevel(level);
174 | _IllusionCamera = FindObjectOfType();
175 |
176 | }
177 |
178 | protected override void CorrectRotationLock()
179 | {
180 | if (_IllusionCamera)
181 | {
182 | var my = VR.Camera.SteamCam.origin;
183 |
184 | _IllusionCameraRotation.SetValue(_IllusionCamera, my.eulerAngles);
185 |
186 | Vector3 b = my.rotation * (Vector3.back * _IllusionCamera.Distance);
187 | my.position = _IllusionCamera.Focus + b;
188 | }
189 | }
190 |
191 | protected override void SyncCameras()
192 | {
193 | if (_IllusionCamera)
194 | {
195 | var my = VR.Camera.SteamCam.origin;
196 |
197 | _IllusionCamera.Set(
198 | my.position + my.forward,
199 | Quaternion.LookRotation(my.forward, my.up).eulerAngles,
200 | 1);
201 | }
202 | }
203 | }
204 | }
205 |
--------------------------------------------------------------------------------
/README_JA.md:
--------------------------------------------------------------------------------
1 | # PlayClubVR
2 |
3 | このMODでプレイクラブがVRで楽しめます。OpenVRを使用しているので、Viveもオキュラスも対応しています。
4 |
5 |
6 | ## 導入方法
7 |
8 | 1. ダウンロードしたファイルを*PlayClub*フォルダーへ解凍
9 | 2. *PlayClubVR.exe*または*PlayClubStudioVR.exe*を起動
10 | 3. それだけでおk
11 |
12 | ※ SteamVRをインストールして起動する必要があります。
13 |
14 | ## モードや操作方法
15 |
16 | PlayClubVRには2つのモードがあります。
17 |
18 | | モード | 解説 |
19 | | ----------- | ------------------- |
20 | | Seated | *デフォルト。*このモードではマウスとキーボードとゲームパッドで入力します。
操作の仕方も大体本ゲームと同じです。UIは大きな画面でユーザーの前で表示されます。|
21 | | Standing | ViveコントローラーやTouchみたいなコントローラーが検出されると自動的にStandingモードに移動します。このモードでは、自由に動けて、コントローラーでイイことが出来ます。|
22 |
23 | ### Seatedモード
24 |
25 | As stated earlier, the controls are basically the same as in the main game with the exception of a few VR-related shortcuts. You are presented with a screen in front of your that replaces your monitor and can be configured via the settings via shortcus (see below).
26 |
27 | #### キーボード
28 |
29 | Keys | Effect
30 | ---- | ------
31 | Ctrl+C, Ctrl+C | Change to *standing mode*.
32 | Ctrl+C, Ctrl+V | Enable (very experimental) third person camera. [Was used for this video](https://www.youtube.com/watch?v=0klN6gd1ybM).
33 | Alt+S | Save settings (IPD, screen position, etc.).
34 | Alt+L | Load settings (last saved state).
35 | Ctrl+Alt+L | Reset settings to the initial state.
36 | F4 | Switch GUI projection mode (flat, curved, spherical).
37 | F5 | Toggle camera lock (enabled by default). This prevents the camera to *tilt* because such movements are known to cause cyber sickness.
38 | Ctrl+F5 | Apply shaders (only for the brave)
39 | F12 | Recenter
40 | Ctrl+X | Impersonate protagonist. Places the camera at the head position of the protagonist and moves along a little.
41 | Ctrl+Shift+X | Impersonate protagonist. Places the camera at the head position of the protagonist and imitates *all* head movements.
42 | NumPad +
NumPad – | Move GUI up / down.
43 | Ctrl+Shift+NumPad +
Ctrl+Shift+NumPad – | Move GUI left / right
44 | Ctrl+NumPad +
Ctrl+NumPad – | Increase / decrease GUI size.
45 | Alt+NumPad +
Alt+NumPad – | Increase / decrease player scale
46 | Shift+NumPad +
Shift+NumPad – | Increase / decrease GUI distance
47 |
48 | #### Gamepad Bindings
49 |
50 | Keys | Effect
51 | ---- | ------
52 | Move LS | Control cursor
53 | Move RS | Rotate & zoom
54 | LT+Move LS | Pan left/right, up/down
55 | LT+Move RS | Rotate camera
56 | RT+Move LS | Pan left/right, foward/backward
57 | RT+Move RS | Rotate camera
58 | A | Left click
59 | B | Right click
60 | X | Toggle "grind" animation
61 | Y | Toggle "piston" animation
62 | Back | Toggle GUI
63 | DPad Up / DPad Down | Change animation speed
64 | DPad Left / DPad Right | Change position (prev / next)
65 | Press RS | Come inside
66 | Press LS | Come outside
67 | LB+LS Horizontally | Move GUI left / right
68 | LB+LS Vertically | Move GUI up / down
69 | LB+RS Horizontally | Change GUI distance
70 | LB+RS Vertically | Change GUI width
71 | LB+DPad Up / LB+DPad Down | Change player scale
72 | LB+Y | Impersonate protatonist
73 |
74 | ### Standing Mode
75 |
76 | The *standing mode* is where things start to get interesting. This mode is pretty much disconnected from the usual game in that it comes with its very own controls -- although you can still use your mouse and your keyboard.
77 |
78 | #### キーボード
79 |
80 | Keys | Effect
81 | ---- | ------
82 | Ctrl+C, Ctrl+C | Change to *standing mode*.
83 | Ctrl+C, Ctrl+V | Enable (very experimental) third person camera. [Was used for this video](https://www.youtube.com/watch?v=0klN6gd1ybM).
84 | Alt+S | Save settings (IPD, screen position, etc.).
85 | Alt+L | Load settings (last saved state).
86 | Ctrl+Alt+L | Reset settings to the initial state.
87 | Ctrl+F5 | Apply shaders (only for the brave)
88 | Alt+NumPad +
Alt+NumPad – | Increase / decrease player scale
89 |
90 | #### 憑依
91 |
92 | *Impersonating* someone is as easy as moving at the position of that character's head. The head will disappear and you can pretend to be him / her. By setting `` you can even control their hands!
93 |
94 | #### Interaction
95 |
96 | Interacting is currently only possible either with the conductor tool (which lets you move around the limbs of characters), or by touching the breasts, hair or skirts of girls. They will then start to wiggle more or less realistically, but it can be fun.
97 |
98 | ## ツール
99 |
100 | These tools are mainly meant to be used in *standing mode* but some of them are also available in *seated mode*.
101 |
102 | ### Menu Tool (seated / standing)
103 |
104 | STUB
105 |
106 | ### Warp Tool (standing)
107 |
108 | STUB
109 |
110 | ### Play Tool (standing)
111 |
112 | STUB
113 |
114 | ### Conductor Tool (seated / standing)
115 |
116 | **Caution:** Requires [Maestro Mode](hongfire.com/forum/showthread.php/440160-%28Illusion%29-Play-Club?p=3667135#post3667135) to work in the main game!
117 |
118 | STUB
119 |
120 | ## 環境設定
121 |
122 | Settings can be changed in the file *vr_settings.xml*, which is generated the first time you start the game. Use `RenderScale` to tweak the resolution, **not** the internal resolution dialog, as that one will currently only change the resolution of the GUI.
123 |
124 | Tag | Default | Effect | Mode
125 | ---- | ------ | ------ | ----
126 | `` | 0.3 | Sets the distance between the camera and the GUI at `[0,0,0]`. | Seated
127 | `` | 170 | Sets the width of the arc the GUI takes up. | Seated
128 | `` | 1 | Sets the scale of the camera. The higher, the more gigantic the player is. | Seated / Standing
129 | `` | 0 | Sets the vertical offset of the GUI in meters. | Seated
130 | `` | 0 | Sets by how many degrees the GUI is rotated (around the y / up axis) | Seated
131 | `` | True | Sets whether or not rumble is activated. | Seated / Standing
132 | `` | 1 | Sets the render scale of the renderer. Increase for better quality but less performance, decrease for more performance but poor quality. | Seated / Standing
133 | `` | False | Sets whether or not the view should be mirrored in the game window. | Seated / Standing
134 | `` | False | Sets whether or not you should take control over the character's hands whenever you impersonate someone. | Standing
135 |
136 | ## Building PlayClubVR
137 |
138 | PlayClubVR depends on the [VRGIN.Core](https://github.com/Eusth/VRGIN.Core) library which is included as a submodule. It is therefore important that when you clone the project, you clone it recursively.
139 |
140 | ```
141 | git clone --recursive https://github.com/Eusth/PlayClubVR.git
142 | cd PlayClubVR
143 | ```
144 |
145 | After cloning the repo and setting up the submodule, you should be able to compile the project by simply opening the *.sln file and building.
146 |
147 | Note that there is a build configuration called "Install" that will extract your Play Club install directory from the registry and copy the files where they belong.
148 |
--------------------------------------------------------------------------------
/Libs/Injector/IllusionPlugin.XML:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | IllusionPlugin
5 |
6 |
7 |
8 |
9 | Gets a list of executables this plugin should be excuted on (without the file ending)
10 |
11 | { "PlayClub", "PlayClubStudio" }
12 |
13 |
14 |
15 | Create a New INI file to store or load data
16 |
17 |
18 |
19 |
20 | INIFile Constructor.
21 |
22 |
23 |
24 |
25 |
26 | Write Data to the INI File
27 |
28 |
29 | Section name
30 |
31 | Key Name
32 |
33 | Value Name
34 |
35 |
36 |
37 | Read Data Value From the Ini File
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | Interface for generic Illusion unity plugins. Every class that implements this will be loaded if the DLL is placed at
47 | data/Managed/Plugins.
48 |
49 |
50 |
51 |
52 | Gets the name of the plugin.
53 |
54 |
55 |
56 |
57 | Gets the version of the plugin.
58 |
59 |
60 |
61 |
62 | Gets invoked when the application is started.
63 |
64 |
65 |
66 |
67 | Gets invoked when the application is closed.
68 |
69 |
70 |
71 |
72 | Gets invoked whenever a level is loaded.
73 |
74 |
75 |
76 |
77 |
78 | Gets invoked after the first update cycle after a level was loaded.
79 |
80 |
81 |
82 |
83 |
84 | Gets invoked on every graphic update.
85 |
86 |
87 |
88 |
89 | Gets invoked on ever physics update.
90 |
91 |
92 |
93 |
94 | Allows to get and set preferences for your mod.
95 |
96 |
97 |
98 |
99 | Gets a string from the ini.
100 |
101 | Section of the key.
102 | Name of the key.
103 | Value that should be used when no value is found.
104 | Whether or not the default value should be written if no value is found.
105 |
106 |
107 |
108 |
109 | Gets an int from the ini.
110 |
111 | Section of the key.
112 | Name of the key.
113 | Value that should be used when no value is found.
114 | Whether or not the default value should be written if no value is found.
115 |
116 |
117 |
118 |
119 | Gets a float from the ini.
120 |
121 | Section of the key.
122 | Name of the key.
123 | Value that should be used when no value is found.
124 | Whether or not the default value should be written if no value is found.
125 |
126 |
127 |
128 |
129 | Gets a bool from the ini.
130 |
131 | Section of the key.
132 | Name of the key.
133 | Value that should be used when no value is found.
134 | Whether or not the default value should be written if no value is found.
135 |
136 |
137 |
138 |
139 | Checks whether or not a key exists in the ini.
140 |
141 | Section of the key.
142 | Name of the key.
143 |
144 |
145 |
146 |
147 | Sets a float in the ini.
148 |
149 | Section of the key.
150 | Name of the key.
151 | Value that should be written.
152 |
153 |
154 |
155 | Sets an int in the ini.
156 |
157 | Section of the key.
158 | Name of the key.
159 | Value that should be written.
160 |
161 |
162 |
163 | Sets a string in the ini.
164 |
165 | Section of the key.
166 | Name of the key.
167 | Value that should be written.
168 |
169 |
170 |
171 | Sets a bool in the ini.
172 |
173 | Section of the key.
174 | Name of the key.
175 | Value that should be written.
176 |
177 |
178 |
179 |
--------------------------------------------------------------------------------
/PlayClubVR/PlayTool.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using UnityEngine;
6 | using UnityEngine.EventSystems;
7 | using UnityEngine.UI;
8 | using Valve.VR;
9 | using VRGIN.Core;
10 | using VRGIN.Controls;
11 | using VRGIN.Helpers;
12 | using VRGIN.Controls.Tools;
13 | using System.Reflection;
14 |
15 | namespace PlayClubVR
16 | {
17 | public class PlayTool : Tool
18 | {
19 | private readonly FieldInfo _DynamicBoneParticleField = typeof(DynamicBone).GetField("m_Particles", BindingFlags.Instance | BindingFlags.NonPublic);
20 | private readonly FieldInfo _DynamicCustomBoneParticleField = typeof(DynamicBone_Custom).GetField("m_Particles", BindingFlags.Instance | BindingFlags.NonPublic);
21 |
22 |
23 | private const float DOT_PRODUCT_THRESHOLD = 0.7f;
24 |
25 | H_Scene scene;
26 | bool _AlteringSpeed;
27 | bool _IgnoreNextTrigger;
28 | private const float NEAR_THRESHOLD = 0.1f;
29 |
30 | public override Texture2D Image
31 | {
32 | get
33 | {
34 | return UnityHelper.LoadImage("icon_play.png");
35 | }
36 | }
37 |
38 | protected override void OnStart()
39 | {
40 | base.OnStart();
41 |
42 | Tracking = GetComponent();
43 | }
44 | protected override void OnFixedUpdate()
45 | {
46 | scene = (VR.Interpreter as PlayClubInterpreter).Scene;
47 | if (scene && IsTracking)
48 | {
49 | var device = this.Controller;
50 |
51 | var tPadPos = device.GetAxis();
52 | var tPadClick = device.GetPressUp(EVRButtonId.k_EButton_SteamVR_Touchpad);
53 | var tPadTouch = device.GetTouch(EVRButtonId.k_EButton_SteamVR_Touchpad);
54 | if (tPadClick)
55 | {
56 | if (Vector2.Dot(Vector2.up, tPadPos) > DOT_PRODUCT_THRESHOLD)
57 | {
58 | Logger.Debug("up");
59 | (VR.Interpreter as PlayClubInterpreter).TogglePiston();
60 | }
61 | else if (Vector2.Dot(-Vector2.up, tPadPos) > DOT_PRODUCT_THRESHOLD)
62 | {
63 | Logger.Debug("down");
64 |
65 | (VR.Interpreter as PlayClubInterpreter).ToggleGrind();
66 | }
67 | else if (Vector2.Dot(-Vector2.right, tPadPos) > DOT_PRODUCT_THRESHOLD)
68 | {
69 | Logger.Debug("left");
70 |
71 | (VR.Interpreter as PlayClubInterpreter).ChangePose(-1);
72 | }
73 | else if (Vector2.Dot(Vector2.right, tPadPos) > DOT_PRODUCT_THRESHOLD)
74 | {
75 | Logger.Debug("right");
76 |
77 | (VR.Interpreter as PlayClubInterpreter).ChangePose(1);
78 | }
79 | }
80 | if (device.GetTouchDown(EVRButtonId.k_EButton_Axis0))
81 | {
82 | if (tPadPos.magnitude < 0.4f)
83 | {
84 | _AlteringSpeed = true;
85 | }
86 | }
87 |
88 | if (_AlteringSpeed && tPadTouch)
89 | {
90 | // Normalize
91 | float val = (tPadPos.y + 1) / 2;
92 | (VR.Interpreter as PlayClubInterpreter).SetSpeed(val);
93 | }
94 | if (device.GetTouchUp(EVRButtonId.k_EButton_Axis0))
95 | {
96 | _AlteringSpeed = false;
97 | }
98 |
99 | //if (device.GetTouchUp(EVRButtonId.k_EButton_Grip))
100 | //{
101 | // ToggleOrgasmLock();
102 | //}
103 |
104 | if (device.GetPressUp(EVRButtonId.k_EButton_Grip))
105 | {
106 | if (_IgnoreNextTrigger)
107 | {
108 | _IgnoreNextTrigger = false;
109 | }
110 | else
111 | {
112 | (VR.Interpreter as PlayClubInterpreter).Ejaculate();
113 | }
114 | }
115 |
116 | if(device.GetPressDown(EVRButtonId.k_EButton_SteamVR_Trigger))
117 | {
118 | AssociateBoneColliders(FindNearBones());
119 | }
120 |
121 | if(device.GetPressUp(EVRButtonId.k_EButton_SteamVR_Trigger))
122 | {
123 | DeassociateBoneColliders();
124 | }
125 | }
126 | }
127 |
128 | private IDictionary> _ColliderOldSelectorMap = new Dictionary>();
129 |
130 | private void AssociateBoneColliders(IEnumerable bones)
131 | {
132 |
133 | IDictionary> colliderBoneMap = new Dictionary>();
134 |
135 | // Find colliders that are responsible for these bones
136 | var colliders = GetComponentsInChildren();
137 | foreach(var bone in bones)
138 | {
139 | var atari = colliders.FirstOrDefault(collider => bone.Colliders.Contains(collider));
140 | if(atari)
141 | {
142 | if(!colliderBoneMap.ContainsKey(atari))
143 | {
144 | colliderBoneMap.Add(atari, new List());
145 | }
146 |
147 | colliderBoneMap[atari].Add(bone);
148 | atari.m_Bound = DynamicBoneCollider.Bound.Inside;
149 | }
150 | }
151 |
152 | // Override the match condition for the responsible colliders to *only* cover these bones and ignore all other (because we changed the m_Bound to INside)
153 | foreach(var colliderBonePair in colliderBoneMap)
154 | {
155 | _ColliderOldSelectorMap[colliderBonePair.Key] = DynamicColliderRegistry.GetCondition(colliderBonePair.Key);
156 | DynamicColliderRegistry.RegisterCollider(colliderBonePair.Key, (collider) => colliderBonePair.Value.Contains(collider));
157 | }
158 | }
159 |
160 |
161 | private void DeassociateBoneColliders()
162 | {
163 | // Revert the changes made in AssociateBoneColliders() by setting the m_Bound to Outside and restoring the old conditions
164 | foreach(var colliderConditionPair in _ColliderOldSelectorMap)
165 | {
166 | colliderConditionPair.Key.m_Bound = DynamicBoneCollider.Bound.Outside;
167 | DynamicColliderRegistry.RegisterCollider(colliderConditionPair.Key, colliderConditionPair.Value);
168 | }
169 |
170 | _ColliderOldSelectorMap.Clear();
171 | }
172 |
173 | private IEnumerable FindNearBones()
174 | {
175 | return DynamicColliderRegistry
176 | .Bones
177 | .Where((bone, i) =>
178 | bone.Nodes.Any( n =>
179 | Vector3.Distance(transform.position, n.position) < NEAR_THRESHOLD
180 | )
181 | );
182 | }
183 |
184 | private void OnImpersonated()
185 | {
186 | _IgnoreNextTrigger = true;
187 | }
188 |
189 | public override List GetHelpTexts()
190 | {
191 | return new List(new HelpText[] {
192 | HelpText.Create("Slide to set speed", FindAttachPosition("trackpad"), new Vector3(0.07f, 0.02f, 0.05f)),
193 | HelpText.Create("Piston", FindAttachPosition("trackpad"), new Vector3(0, 0.02f, 0.05f), new Vector3(0, 0.0f, 0.015f)),
194 | HelpText.Create("Grind", FindAttachPosition("trackpad"), new Vector3(0, 0.02f, -0.05f), new Vector3(0, 0.0f, -0.015f)),
195 | HelpText.Create("Next animation", FindAttachPosition("trackpad"), new Vector3(0.05f, 0.02f, 0), new Vector3(+0.015f, 0.0f, 0)),
196 | HelpText.Create("Prev animation", FindAttachPosition("trackpad"), new Vector3(-0.05f, 0.02f, 0), new Vector3(-0.015f, 0.0f, 0)),
197 | //HelpText.Create("Toggle lock", FindAttachPosition("lgrip"), new Vector3(-0.05f, 0.02f, 0)),
198 | HelpText.Create("Ejaculate", FindAttachPosition("lgrip"), new Vector3(0.05f, 0.02f, -0.05f)),
199 | });
200 | }
201 |
202 | protected override void OnDestroy()
203 | {
204 | }
205 | }
206 | }
207 |
--------------------------------------------------------------------------------
/PlayClubStudioVR/IKTool.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Reflection;
5 | using System.Text;
6 | using UnityEngine;
7 | using Valve.VR;
8 | using VRGIN.Core;
9 | using VRGIN.Controls;
10 | using VRGIN.Helpers;
11 | using VRGIN.Controls.Tools;
12 | using UnityEngine.UI;
13 |
14 | namespace PlayClubStudioVR
15 | {
16 | static class IKCtrl
17 | {
18 | public enum IKVisibility
19 | {
20 | Deactivated,
21 | Hidden,
22 | Visible
23 | }
24 | public enum IKState
25 | {
26 | FK,
27 | IK
28 | }
29 |
30 | public static IKState State { get { return _State; } private set { _State = value; } }
31 | private static IKState _State = IKState.FK;
32 | public static IKVisibility Visibility { get { return _Visibility; } private set { _Visibility = value; } }
33 | private static IKVisibility _Visibility = IKVisibility.Deactivated;
34 |
35 |
36 | public static event EventHandler StateChanged = delegate { };
37 |
38 |
39 | internal static void Change(IKVisibility _visibility, IKState _state)
40 | {
41 | Visibility = _visibility;
42 | State = _state;
43 |
44 | foreach (var actor in VR.Interpreter.Actors.OfType())
45 | {
46 | bool ikState = Visibility == IKVisibility.Visible && State == IKState.IK;
47 | bool fkState = Visibility == IKVisibility.Visible && State == IKState.FK;
48 |
49 | bool isActive = actor.Actor.fkCtrl.IsActive;
50 |
51 | if (Visibility == IKVisibility.Visible || Visibility == IKVisibility.Deactivated)
52 | {
53 | actor.Actor.ikCtrl.SetActive(ikState);
54 | actor.Actor.fkCtrl.SetActive(ikState || fkState);
55 | }
56 |
57 | actor.Actor.ikCtrl.SetActiveTargets(ikState);
58 | actor.Actor.fkCtrl.SetActiveTargets(fkState);
59 |
60 | if (ikState)
61 | {
62 | actor.Actor.ikCtrl.SetupIK();
63 | if (!isActive)
64 | {
65 | actor.Actor.fkCtrl.SetupFK();
66 | }
67 | }
68 | else if (fkState)
69 | {
70 | actor.Actor.fkCtrl.SetupFK();
71 | }
72 | }
73 |
74 | StateChanged(null, null);
75 | }
76 |
77 | internal static void Show()
78 | {
79 | if(Visibility == IKVisibility.Hidden)
80 | {
81 | Change(IKVisibility.Visible, State);
82 | }
83 | }
84 |
85 | internal static void Enable()
86 | {
87 | if (Visibility == IKVisibility.Deactivated)
88 | {
89 | Change(IKVisibility.Visible, State);
90 | }
91 | }
92 |
93 | internal static void Disable()
94 | {
95 | if (Visibility > IKVisibility.Deactivated)
96 | {
97 | Change(IKVisibility.Deactivated, State);
98 | }
99 | }
100 |
101 | internal static void Hide()
102 | {
103 | if (Visibility > IKVisibility.Hidden)
104 | {
105 | Change(IKVisibility.Hidden, State);
106 | }
107 | }
108 |
109 | internal static void Toggle()
110 | {
111 | var newState = (IKState)(((int)State + 1) % Enum.GetValues(typeof(IKState)).Length);
112 | Change(Visibility, newState);
113 | }
114 | }
115 | class IKTool : Tool
116 | {
117 |
118 | private class IKStateReactor : ProtectedBehaviour
119 | {
120 | private Text textElement;
121 | protected override void OnAwake()
122 | {
123 | base.OnAwake();
124 | textElement = GetComponent();
125 | }
126 |
127 | void OnEnable()
128 | {
129 | IKCtrl.StateChanged += OnStateChanged;
130 |
131 | OnStateChanged(null, null);
132 | }
133 |
134 | void OnDisable()
135 | {
136 | IKCtrl.StateChanged -= OnStateChanged;
137 | }
138 |
139 | private void OnStateChanged(object sender, EventArgs e)
140 | {
141 | textElement.text = IKCtrl.Visibility == IKCtrl.IKVisibility.Visible
142 | ? IKCtrl.State.ToString()
143 | : "-";
144 | }
145 | }
146 |
147 | private const float MAX_DISTANCE = 0.5f;
148 |
149 | private static string[] BLACKLIST = new string[] { "XY", "YZ", "XZ", "RingGuidZ", "RingGuidX", "RingGuidY" };
150 | private readonly static int GIZMO_LAYER = LayerMask.NameToLayer("DriveUI");
151 | private bool _Dragging = false;
152 | private TravelDistanceRumble _Rumble;
153 | private Controller.Lock _Lock;
154 | private Transform _Target;
155 | private FieldInfo _GuideDriveManager = typeof(GuideDrive).GetField("manager", BindingFlags.NonPublic | BindingFlags.Instance);
156 |
157 | private Vector3 _PrevPos;
158 | private Quaternion _PrevRot;
159 | private GuideDriveManager _Manager;
160 | private bool _Hover;
161 | private GameObject _HoverObject;
162 | private Canvas _Canvas;
163 |
164 | public override Texture2D Image
165 | {
166 | get
167 | {
168 | return UnityHelper.LoadImage("icon_maestro.png");
169 | }
170 | }
171 |
172 | public override List GetHelpTexts()
173 | {
174 | return new List(new HelpText[] {
175 | HelpText.Create("Switch FK/IK", FindAttachPosition("trackpad"), new Vector3(0.07f, 0.02f, 0.05f)),
176 | HelpText.Create("Grab", FindAttachPosition("trigger"), new Vector3(0.06f, 0.04f, -0.05f)),
177 | HelpText.Create("Grab", FindAttachPosition("trigger"), new Vector3(0.06f, 0.04f, -0.05f)),
178 | });
179 | }
180 |
181 | protected override void OnStart()
182 | {
183 | base.OnStart();
184 | _Rumble = new TravelDistanceRumble(300, 0.05f, transform);
185 |
186 | CreateIndicatorCanvas();
187 | }
188 |
189 | protected override void OnDisable()
190 | {
191 | base.OnDisable();
192 | Owner.StopRumble(_Rumble);
193 |
194 | if(!(Owner.Other.ActiveTool is IKTool))
195 | {
196 | IKCtrl.Hide();
197 | }
198 |
199 | if(_Canvas)
200 | {
201 | _Canvas.gameObject.SetActive(false);
202 | }
203 | }
204 |
205 | protected override void OnEnable()
206 | {
207 | base.OnEnable();
208 | IKCtrl.Show();
209 |
210 | if (_Canvas)
211 | {
212 | _Canvas.gameObject.SetActive(true);
213 | }
214 | }
215 |
216 | protected override void OnFixedUpdate()
217 | {
218 | base.OnFixedUpdate();
219 |
220 | if(Tracking.isValid)
221 | {
222 | var device = Controller;
223 | if(device.GetPressDown(EVRButtonId.k_EButton_SteamVR_Trigger)) {
224 | _HoverObject = FindNearestHandle();
225 | if (!_HoverObject) return;
226 |
227 | _Manager = (_GuideDriveManager.GetValue(_HoverObject.GetComponent()) as GuideDriveManager);
228 | _PrevPos = transform.position;
229 | _PrevRot = transform.rotation;
230 | _Dragging = true;
231 | Owner.StartRumble(_Rumble);
232 | }
233 | if (_HoverObject)
234 | {
235 | if (device.GetPress(EVRButtonId.k_EButton_SteamVR_Trigger))
236 | {
237 | _Manager.DriveMovePosition(transform.position - _PrevPos);
238 |
239 | var rotDiff = (transform.rotation) * Quaternion.Inverse(_PrevRot);
240 | _Manager.DriveMoveRotation(Quaternion.Inverse(_Manager.rotRoot.rotation) * rotDiff * _Manager.rotRoot.rotation);
241 |
242 | _PrevPos = transform.position;
243 | _PrevRot = transform.rotation;
244 | }
245 | if (device.GetPressUp(EVRButtonId.k_EButton_SteamVR_Trigger))
246 | {
247 | _Dragging = false;
248 | Release();
249 | Owner.StopRumble(_Rumble);
250 | }
251 | }
252 | if(device.GetPressDown(EVRButtonId.k_EButton_SteamVR_Touchpad))
253 | {
254 | if (IKCtrl.Visibility == IKCtrl.IKVisibility.Deactivated)
255 | {
256 | IKCtrl.Enable();
257 | }
258 | else
259 | {
260 | IKCtrl.Toggle();
261 | }
262 | }
263 | if (device.GetPressDown(EVRButtonId.k_EButton_Grip))
264 | {
265 | if (IKCtrl.Visibility == IKCtrl.IKVisibility.Deactivated)
266 | {
267 | IKCtrl.Enable();
268 | }
269 | else
270 | {
271 | IKCtrl.Disable();
272 | }
273 | }
274 | }
275 | }
276 |
277 | private GameObject FindNearestHandle()
278 | {
279 | var nearest = GameObject.FindObjectsOfType().OrderBy(g => Vector3.Distance(g.transform.position, transform.position)).FirstOrDefault();
280 | if(nearest)
281 | {
282 | if (Vector3.Distance(nearest.transform.position, transform.position) <= MAX_DISTANCE)
283 | {
284 | return nearest.gameObject;
285 | }
286 | }
287 | return null;
288 | }
289 |
290 | private void Release()
291 | {
292 | _HoverObject = null;
293 | }
294 |
295 | protected override void OnDestroy()
296 | {
297 | }
298 |
299 | private void CreateIndicatorCanvas()
300 | {
301 | var canvas = _Canvas = UnityHelper.CreateGameObjectAsChild("IKFK", FindAttachPosition("trackpad")).gameObject.AddComponent