Compare commits

...

108 Commits

Author SHA1 Message Date
hecomi
1c1381a7ba consider clipPos and clipScale for raycast #23. 2018-09-12 00:04:33 +09:00
hecomi
08903cd27a fix orientation of monitor object in Zoom scene. 2018-09-12 00:03:36 +09:00
hecomi
d840983829 update Unity version to 2018.2.7f1. 2018-09-12 00:03:01 +09:00
hecomi
8a6cee9c2d Merge pull request #24 from dj-kusuha/fix_il2cpp_runtime_error
fixed a runtime error when using the IL2CPP scripting backend
2018-09-11 21:36:08 +09:00
dj-kusuha
f7798f752f fixed a runtime error when using the IL2CPP scripting backend 2018-09-11 11:27:43 +09:00
hecomi
70cfad90a9 fix bug that caused darker screen #22. 2018-08-05 00:20:03 +09:00
hecomi
c926127e49 update Unity version to 2018.1. 2018-08-05 00:19:07 +09:00
hecomi
03469ce429 remove unnecessary line break. 2018-08-05 00:18:42 +09:00
hecomi
f63e573f04 remove unnecessary logs. 2018-05-20 15:53:30 +09:00
hecomi
682553a5a2 tweak code. 2018-05-20 02:08:18 +09:00
hecomi
b5fd483d6a call ReleaseFrame() just before AcquireNextFrame() #18. 2018-05-20 01:11:03 +09:00
hecomi
0d2c0e02f0 update Visual Studio version to 2017. 2018-05-20 00:53:36 +09:00
hecomi
6f876f65ed update Unity version to 2017.4. 2018-05-19 21:49:24 +09:00
hecomi
8434d803bb remove build status. 2017-08-24 01:38:00 +09:00
hecomi
1c332ebca7 fix bugs that caused x86 build problem. 2017-08-24 01:34:53 +09:00
hecomi
340e2d5194 remove unnecessary shared flag from cursor texture. 2017-01-09 17:07:26 +09:00
hecomi
e397f5eb84 fix typo. 2017-01-08 01:01:05 +09:00
hecomi
c20c09e275 fix bug that drew cursor on all monitors. 2017-01-08 00:38:01 +09:00
hecomi
a0ca46630e fix perf macro bug. 2017-01-08 00:32:14 +09:00
hecomi
5b5995d7d0 remove unnecessary perf. 2017-01-08 00:29:04 +09:00
hecomi
808a71ed6d remove unnecessary codes. 2017-01-08 00:09:24 +09:00
hecomi
da072aa9f3 draw cursor texture to unity texture instead of cached texture. 2017-01-08 00:02:41 +09:00
hecomi
7237d283ef add error messages. 2017-01-07 23:10:13 +09:00
hecomi
4a28b5f341 tweak shared texture. 2017-01-07 23:02:48 +09:00
hecomi
10091be4b3 lock shared texture. 2017-01-07 15:28:13 +09:00
hecomi
c41fe42aa3 check frame id. 2017-01-07 13:48:38 +09:00
hecomi
c0e1967e2e modify duplicator state handling. 2017-01-07 13:26:28 +09:00
hecomi
f5a8a83c7e change member name. 2017-01-07 13:18:11 +09:00
hecomi
c251de3a30 add debug timer macro. 2017-01-07 01:15:33 +09:00
hecomi
b0877a49ed tweak code. 2017-01-07 00:53:37 +09:00
hecomi
68d9e30816 allow buffer copy. 2017-01-06 18:44:43 +09:00
hecomi
b8ae1d6c4a remove unused code. 2017-01-06 18:11:18 +09:00
hecomi
15624dc0f4 add frame rate setter and calc more accurate sleep duration. 2017-01-06 18:07:35 +09:00
hecomi
06d4edbcb0 add timeout to avoid unnecessarily high cpu usage. 2017-01-06 17:53:16 +09:00
hecomi
9ee2d35175 replace code to copy texture with old one #11 2017-01-06 17:32:10 +09:00
hecomi
0634993bb0 prepare multiple texture buffer for each device to avoid flickering cursor #11 2017-01-06 17:29:09 +09:00
hecomi
6bd892bc4b remove unused code. 2017-01-06 16:34:02 +09:00
hecomi
2a631a0a89 add mutex for debug logs. 2017-01-06 16:17:08 +09:00
hecomi
0833b965e9 rename GetFrame() to GetLastFrame(). 2017-01-06 16:14:10 +09:00
hecomi
12726d85dc fix cursor bugs #11 2017-01-06 13:52:23 +09:00
hecomi
29920b6b94 fix bug that blocked stopping scene #12 2017-01-06 04:02:24 +09:00
hecomi
4de8f0ba51 remove unused code. 2017-01-06 03:47:48 +09:00
hecomi
476be8243a remove unused code. 2017-01-06 03:42:48 +09:00
hecomi
c681e43d65 Merge branch 'ousttrue-AcquireNextFrame_on_thread' 2017-01-05 21:21:32 +09:00
hecomi
ed24ca2fb2 add x86 dll and remove pdb file #10 2017-01-05 21:20:35 +09:00
hecomi
791fa42478 fix crash bug when stopping scene #10 2017-01-05 21:13:25 +09:00
hecomi
11dbb7be57 update cursor in each thread #10 2017-01-05 19:38:30 +09:00
hecomi
9ed24dd3b1 modify timing to fetch metadata and add it to frame data #10 2017-01-05 19:03:29 +09:00
hecomi
cfbd218374 fix styles. 2017-01-05 19:03:28 +09:00
hecomi
bf7174f406 initialize at first #10 2017-01-05 19:03:28 +09:00
hecomi
4a761a06f3 remove const_cast #10 2017-01-05 19:03:28 +09:00
hecomi
1effd65aeb add Duplicator class to modularize duplication function #10 2017-01-05 19:03:28 +09:00
hecomi
46cc789be5 spearate IsolatedD3D11Device into different files #10 2017-01-05 19:03:28 +09:00
hecomi
1053b30d7e remove ThreadedDesktopDuplicator.cpp #10 2017-01-05 19:03:28 +09:00
hecomi
d58855ff8a check ReleaseFrame result #10 2017-01-05 19:03:18 +09:00
hecomi
741e2c0bc1 remove useThread flag #10 2017-01-05 12:14:03 +09:00
ousttrue
f6ce875463 call AcquireNextFrame on isolated thread 2016-12-28 02:12:03 +09:00
hecomi
e6407d1c3b modify raycast. 2016-12-18 14:57:31 +09:00
hecomi
620a0f3150 calculate coordinates of raycast hit point. 2016-12-15 22:17:12 +09:00
hecomi
d519dba120 add raycast api. 2016-12-15 02:30:04 +09:00
hecomi
295b41f57b fix standard shader normal bug. 2016-12-04 11:59:08 +09:00
hecomi
6a8bd86d2b fix thickness bug. 2016-12-03 23:27:31 +09:00
hecomi
22bc306732 fix zoom bug. 2016-12-03 23:15:37 +09:00
hecomi
3ed37d1436 tweak scenes. 2016-12-03 23:15:32 +09:00
hecomi
03419f2918 make monitor rotation setter private. 2016-12-03 22:34:49 +09:00
hecomi
2ee8ba35b7 add monitor rotation to editor. 2016-12-03 21:24:32 +09:00
hecomi
2a536ce018 fix scene loop bug. 2016-12-03 21:22:01 +09:00
hecomi
54531a90f3 add texture editor. 2016-12-03 21:18:12 +09:00
hecomi
ae8323fe29 add 32-bit dll. 2016-12-03 01:05:45 +09:00
hecomi
d23fe2fc3d fix indent. 2016-12-01 22:42:17 +09:00
hecomi
81bc23d0bc fix bug that destroyed texture in non-main thread. 2016-12-01 22:34:35 +09:00
hecomi
583af4ff46 Change the way to get pixels and finish the implementation of the APIs 🎉 2016-12-01 22:29:52 +09:00
hecomi
7e3df8ec2e add GetPixels() and GetPixel() APIs (wip). 2016-11-30 02:40:16 +09:00
hecomi
32adf6c2d0 fix out-of-area bug. 2016-11-29 20:10:05 +09:00
hecomi
a24472bd92 fix cursor capture area bug. 2016-11-29 20:02:02 +09:00
hecomi
cfee22832a fix indent. 2016-11-28 02:31:55 +09:00
hecomi
9c467a0e6f fix indent. 2016-11-28 02:31:17 +09:00
hecomi
87557ed5ff refactoring. 2016-11-28 02:30:09 +09:00
hecomi
67c90073d9 fix unity log call from native. 2016-11-27 16:22:03 +09:00
hecomi
ce9c148282 remove unused code and fix minor bug. 2016-11-27 15:48:09 +09:00
hecomi
8201a22523 move cursor owner from monitor to manager. 2016-11-27 14:44:23 +09:00
hecomi
5cfbd70e0b output monitor orientation in log. 2016-11-27 13:54:42 +09:00
hecomi
f2b6a99af3 modify the mothod to check monitor orientation. 2016-11-26 18:11:02 +09:00
hecomi
c48bf7fecf add displacement mapping example. 2016-11-26 17:50:03 +09:00
hecomi
6673734b9c remove Cursor-related codes because they were handled directly in the native code. 2016-11-26 16:31:34 +09:00
hecomi
3364c19adf add displacement shader. 2016-11-26 16:14:00 +09:00
hecomi
f7eba2434f fix bug #2 that causes crash after returning from UAC. 2016-11-24 23:38:07 +09:00
hecomi
ddbfad6e95 upload cursor texture in native plugin. 2016-11-20 22:35:52 +09:00
hecomi
49aef432e7 improve performance. 2016-11-20 15:59:06 +09:00
hecomi
fc81892917 cache cursor texture pointer to improve performance. 2016-11-20 15:41:47 +09:00
hecomi
306a656c4e add gaze point analyzer for multiple monitors. 2016-11-20 15:15:19 +09:00
hecomi
faf65b4200 support hot-reload. 2016-11-20 14:32:31 +09:00
hecomi
ab25af516e do not loop generation of monitors in creator. 2016-11-20 12:38:24 +09:00
hecomi
45b0ab2cd8 save scale even after reinitialization. 2016-11-20 03:27:16 +09:00
hecomi
68227e9af6 remove unused debug log. 2016-11-20 03:03:40 +09:00
hecomi
be9871ba92 fix thickness bug. 2016-11-20 02:57:31 +09:00
hecomi
110d5d7bda fix boudary condition of cursor texture. 2016-11-20 02:54:38 +09:00
hecomi
533a4c9f28 add gaze point analyzer. 2016-11-20 02:49:58 +09:00
hecomi
88e8342d7a tweak scenes. 2016-11-19 21:55:25 +09:00
hecomi
72376b9e91 implement dirty rects and move rects. 2016-11-19 21:45:32 +09:00
hecomi
a10d5aa5c1 add buffer class. 2016-11-19 15:37:35 +09:00
hecomi
306185a1e9 add badges. 2016-11-19 13:56:16 +09:00
hecomi
60889d53f4 modify layouter to fix height. 2016-11-19 13:49:38 +09:00
hecomi
f207e65952 do not stop initialization even when getting dpi has error. 2016-11-19 13:09:50 +09:00
hecomi
aea8d112c6 fix indent. 2016-11-18 02:33:24 +09:00
hecomi
9f6971dd45 register callbacks. 2016-11-18 02:28:27 +09:00
hecomi
1be698af63 keep local scale of monitors as 1. 2016-11-18 00:19:22 +09:00
hecomi
064db9f137 modify access rights of layouter. 2016-11-17 23:31:39 +09:00
111 changed files with 5962 additions and 916 deletions

3
.gitignore vendored
View File

@@ -5,6 +5,8 @@
/[Bb]uild/
/[Ww]iki/
/[Mm]isc/
/UnityPackageManager
/Packages
# Autogenerated VS/MD solution and project files
*.csproj
@@ -28,3 +30,4 @@ sysinfo.txt
/Assets/AssetStoreTools*
/Assets/Extensions*
/uDesktopDuplication.log
.vs

View File

@@ -0,0 +1,119 @@
using UnityEngine;
using UnityEditor;
using System.Linq;
namespace uDesktopDuplication
{
[CustomEditor(typeof(Texture))]
public class TextureEditor : Editor
{
Texture texture
{
get { return target as Texture; }
}
Monitor monitor
{
get { return texture.monitor; }
}
bool isAvailable
{
get { return monitor == null || !Application.isPlaying; }
}
bool basicsFolded_ = true;
bool invertFolded_ = true;
bool clipFolded_ = true;
bool matFolded_ = true;
SerializedProperty invertX_;
SerializedProperty invertY_;
SerializedProperty useClip_;
SerializedProperty clipPos_;
SerializedProperty clipScale_;
void OnEnable()
{
invertX_ = serializedObject.FindProperty("invertX_");
invertY_ = serializedObject.FindProperty("invertY_");
useClip_ = serializedObject.FindProperty("useClip_");
clipPos_ = serializedObject.FindProperty("clipPos");
clipScale_ = serializedObject.FindProperty("clipScale");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.Space();
DrawMonitor();
DrawInvert();
DrawClip();
DrawMaterial();
serializedObject.ApplyModifiedProperties();
}
void Fold(string name, ref bool folded, System.Action func)
{
folded = Utils.Foldout(name, folded);
if (folded) {
++EditorGUI.indentLevel;
func();
--EditorGUI.indentLevel;
}
}
void DrawMonitor()
{
Fold("Monitor", ref basicsFolded_, () => {
if (isAvailable) {
EditorGUILayout.HelpBox("Monitor information is available only in runtime.", MessageType.Info);
return;
}
var id = EditorGUILayout.Popup("Monitor", monitor.id, Manager.monitors.Select(x => x.name).ToArray());
if (id != monitor.id) { texture.monitorId = id; }
EditorGUILayout.IntField("ID", monitor.id);
EditorGUILayout.Toggle("Is Primary", monitor.isPrimary);
EditorGUILayout.EnumPopup("Rotation", monitor.rotation);
EditorGUILayout.Vector2Field("Resolution", new Vector2(monitor.width, monitor.height));
EditorGUILayout.Vector2Field("DPI", new Vector2(monitor.dpiX, monitor.dpiY));
});
}
void DrawInvert()
{
Fold("Invert", ref invertFolded_, () => {
texture.invertX = EditorGUILayout.Toggle("Invert X", invertX_.boolValue);
texture.invertY = EditorGUILayout.Toggle("Invert Y", invertY_.boolValue);
});
}
void DrawClip()
{
Fold("Clip", ref clipFolded_, () => {
texture.useClip = EditorGUILayout.Toggle("Use Clip", useClip_.boolValue);
EditorGUILayout.PropertyField(clipPos_);
EditorGUILayout.PropertyField(clipScale_);
});
}
void DrawMaterial()
{
Fold("Material", ref matFolded_, () => {
if (!Application.isPlaying) {
EditorGUILayout.HelpBox("These parameters are applied to the shared material when not playing.", MessageType.Info);
}
texture.meshForwardDirection = (Texture.MeshForwardDirection)EditorGUILayout.EnumPopup("Mesh Forward Direction", texture.meshForwardDirection);
texture.bend = EditorGUILayout.Toggle("Use Bend", texture.bend);
texture.width = EditorGUILayout.FloatField("Bend Width", texture.width);
texture.radius = EditorGUILayout.Slider("Bend Radius", texture.radius, texture.worldWidth / (2 * Mathf.PI), 100f);
texture.thickness = EditorGUILayout.Slider("Thickness", texture.thickness, 0f, 30f);
texture.culling = (Texture.Culling)EditorGUILayout.EnumPopup("Culling", texture.culling);
});
}
}
}

View File

@@ -1,12 +1,12 @@
fileFormatVersion: 2
guid: d2d9e4ca459ecb44da8815bafe9655c5
timeCreated: 1477635630
guid: 1202a4540abf0ad4781c025339772c4a
timeCreated: 1480758898
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 89616e59e1cccb346bd4e959257990ca, type: 3}
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,46 @@
using UnityEngine;
using UnityEditor;
namespace uDesktopDuplication
{
public static class Utils
{
public static bool Foldout(string title, bool display)
{
var style = new GUIStyle("ShurikenModuleTitle");
style.font = new GUIStyle(EditorStyles.label).font;
style.border = new RectOffset(15, 7, 4, 4);
style.fixedHeight = 22;
style.contentOffset = new Vector2(20f, -2f);
var rect = GUILayoutUtility.GetRect(16f, 22f, style);
GUI.Box(rect, title, style);
var e = Event.current;
var toggleRect = new Rect(rect.x + 4f, rect.y + 2f, 13f, 13f);
if (e.type == EventType.Repaint) {
EditorStyles.foldout.Draw(toggleRect, false, false, display, false);
}
if (e.type == EventType.MouseDown && rect.Contains(e.mousePosition)) {
display = !display;
e.Use();
}
return display;
}
public static void ReadOnlyTextField(string label, string text)
{
EditorGUILayout.BeginHorizontal();
{
EditorGUILayout.LabelField(label, GUILayout.Width(EditorGUIUtility.labelWidth - 4));
EditorGUILayout.SelectableLabel(text, EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight));
}
EditorGUILayout.EndHorizontal();
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 278117152a6252546a219a17ef6f21f4
timeCreated: 1480759393
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,116 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1001 &100100000
Prefab:
m_ObjectHideFlags: 1
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications: []
m_RemovedComponents: []
m_ParentPrefab: {fileID: 0}
m_RootGameObject: {fileID: 1000012030065192}
m_IsPrefabParent: 1
--- !u!1 &1000012030065192
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 4000012948588652}
- component: {fileID: 33000012667387780}
- component: {fileID: 23000013406986662}
- component: {fileID: 114000010662012988}
- component: {fileID: 114000012475682042}
m_Layer: 0
m_Name: Monitor Plane for Displacement Mapping
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &4000012948588652
Transform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1000012030065192}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 10}
m_LocalScale: {x: 1.92, y: 1, z: 1.08}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!23 &23000013406986662
MeshRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1000012030065192}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 596fd740aeeee0d4cb4f962d4072954e, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_PreserveUVs: 1
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
--- !u!33 &33000012667387780
MeshFilter:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1000012030065192}
m_Mesh: {fileID: 4300000, guid: f30f6cfd6aa37554ca886424cada7cbb, type: 3}
--- !u!114 &114000010662012988
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1000012030065192}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: bb54a34570e4747429b1c5b66c69d356, type: 3}
m_Name:
m_EditorClassIdentifier:
invertX_: 0
invertY_: 0
useClip_: 0
clipPos: {x: 0, y: 0}
clipScale: {x: 0.2, y: 0.2}
--- !u!114 &114000012475682042
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1000012030065192}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 859a2446b86e55c43932212872c82748, type: 3}
m_Name:
m_EditorClassIdentifier:
target: 0
displacementFactor: 0.1
tessellationMinDist: 0.5
tessellationMaxDist: 10
tessellationFactor: 25

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 57d4a6e606848364c9880f2adec16d90
timeCreated: 1480074774
licenseType: Pro
NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,99 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1001 &100100000
Prefab:
m_ObjectHideFlags: 1
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications: []
m_RemovedComponents: []
m_ParentPrefab: {fileID: 0}
m_RootGameObject: {fileID: 1000010241636970}
m_IsPrefabParent: 1
--- !u!1 &1000010241636970
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 4000010860913228}
- component: {fileID: 33000013746893738}
- component: {fileID: 23000010406152182}
- component: {fileID: 114000011004997192}
m_Layer: 0
m_Name: Monitor Unity Plane
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &4000010860913228
Transform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1000010241636970}
m_LocalRotation: {x: -0.7071068, y: 0, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0, y: 0, z: 10}
m_LocalScale: {x: 1.92, y: 1, z: 1.08}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: -90, y: 0, z: 0}
--- !u!23 &23000010406152182
MeshRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1000010241636970}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: c181d333a7bee7a44b94c0f4e02c4bd4, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_PreserveUVs: 1
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
--- !u!33 &33000013746893738
MeshFilter:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1000010241636970}
m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0}
--- !u!114 &114000011004997192
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1000010241636970}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: bb54a34570e4747429b1c5b66c69d356, type: 3}
m_Name:
m_EditorClassIdentifier:
invertX_: 0
invertY_: 0
useClip_: 0
clipPos: {x: 0, y: 0}
clipScale: {x: 0.2, y: 0.2}

View File

@@ -0,0 +1,440 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
OcclusionCullingSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: 0.25
backfaceThreshold: 100
m_SceneGUID: 00000000000000000000000000000000
m_OcclusionCullingData: {fileID: 0}
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 8
m_Fog: 0
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
m_FogMode: 3
m_FogDensity: 0.01
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 0
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
m_HaloStrength: 0.5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 11
m_GIWorkflowMode: 0
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_TemporalCoherenceThreshold: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 1
m_LightmapEditorSettings:
serializedVersion: 9
m_Resolution: 2
m_BakeResolution: 40
m_TextureWidth: 1024
m_TextureHeight: 1024
m_AO: 0
m_AOMaxDistance: 1
m_CompAOExponent: 0
m_CompAOExponentDirect: 0
m_Padding: 2
m_LightmapParameters: {fileID: 0}
m_LightmapsBakeMode: 1
m_TextureCompression: 1
m_FinalGather: 0
m_FinalGatherFiltering: 1
m_FinalGatherRayCount: 1024
m_ReflectionCompression: 2
m_MixedBakeMode: 1
m_BakeBackend: 0
m_PVRSampling: 1
m_PVRDirectSampleCount: 32
m_PVRSampleCount: 500
m_PVRBounces: 2
m_PVRFiltering: 0
m_PVRFilteringMode: 1
m_PVRCulling: 1
m_PVRFilteringGaussRadiusDirect: 1
m_PVRFilteringGaussRadiusIndirect: 5
m_PVRFilteringGaussRadiusAO: 2
m_PVRFilteringAtrousColorSigma: 1
m_PVRFilteringAtrousNormalSigma: 1
m_PVRFilteringAtrousPositionSigma: 1
m_LightingDataAsset: {fileID: 0}
m_UseShadowmask: 0
--- !u!196 &4
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 2
agentTypeID: 0
agentRadius: 0.5
agentHeight: 2
agentSlope: 45
agentClimb: 0.4
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
minRegionArea: 2
manualCellSize: 0
cellSize: 0.16666667
manualTileSize: 0
tileSize: 256
accuratePlacement: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &79264388
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_Component:
- component: {fileID: 79264393}
- component: {fileID: 79264392}
- component: {fileID: 79264391}
- component: {fileID: 79264390}
- component: {fileID: 79264389}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!81 &79264389
AudioListener:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 79264388}
m_Enabled: 1
--- !u!124 &79264390
Behaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 79264388}
m_Enabled: 1
--- !u!92 &79264391
Behaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 79264388}
m_Enabled: 1
--- !u!20 &79264392
Camera:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 79264388}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 1
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0.019607844}
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: 0.3
far clip plane: 1000
field of view: 60
orthographic: 0
orthographic size: 5
m_Depth: -1
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 0
m_AllowMSAA: 1
m_ForceIntoRT: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: 0.022
m_StereoMirrorMode: 0
--- !u!4 &79264393
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 79264388}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: -3}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &913398332
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 1000012030065192, guid: 57d4a6e606848364c9880f2adec16d90,
type: 2}
m_PrefabInternal: {fileID: 1607746357}
serializedVersion: 5
m_Component:
- component: {fileID: 913398337}
- component: {fileID: 913398336}
- component: {fileID: 913398335}
- component: {fileID: 913398334}
- component: {fileID: 913398333}
m_Layer: 0
m_Name: Monitor Plane for Displacement Mapping
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &913398333
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 114000012475682042, guid: 57d4a6e606848364c9880f2adec16d90,
type: 2}
m_PrefabInternal: {fileID: 1607746357}
m_GameObject: {fileID: 913398332}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 859a2446b86e55c43932212872c82748, type: 3}
m_Name:
m_EditorClassIdentifier:
target: 0
displacementFactor: 0.1
tessellationMinDist: 0.5
tessellationMaxDist: 10
tessellationFactor: 25
--- !u!114 &913398334
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 114000010662012988, guid: 57d4a6e606848364c9880f2adec16d90,
type: 2}
m_PrefabInternal: {fileID: 1607746357}
m_GameObject: {fileID: 913398332}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: bb54a34570e4747429b1c5b66c69d356, type: 3}
m_Name:
m_EditorClassIdentifier:
invertX_: 0
invertY_: 0
useClip_: 0
clipPos: {x: 0, y: 0}
clipScale: {x: 0.2, y: 0.2}
--- !u!23 &913398335
MeshRenderer:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 23000013406986662, guid: 57d4a6e606848364c9880f2adec16d90,
type: 2}
m_PrefabInternal: {fileID: 1607746357}
m_GameObject: {fileID: 913398332}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 596fd740aeeee0d4cb4f962d4072954e, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_PreserveUVs: 1
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
--- !u!33 &913398336
MeshFilter:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 33000012667387780, guid: 57d4a6e606848364c9880f2adec16d90,
type: 2}
m_PrefabInternal: {fileID: 1607746357}
m_GameObject: {fileID: 913398332}
m_Mesh: {fileID: 4300000, guid: f30f6cfd6aa37554ca886424cada7cbb, type: 3}
--- !u!4 &913398337
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 4000012948588652, guid: 57d4a6e606848364c9880f2adec16d90,
type: 2}
m_PrefabInternal: {fileID: 1607746357}
m_GameObject: {fileID: 913398332}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 10}
m_LocalScale: {x: 1.92, y: 1, z: 1.08}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1001 &1607746357
Prefab:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications:
- target: {fileID: 4000012948588652, guid: 57d4a6e606848364c9880f2adec16d90, type: 2}
propertyPath: m_LocalPosition.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 4000012948588652, guid: 57d4a6e606848364c9880f2adec16d90, type: 2}
propertyPath: m_LocalPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 4000012948588652, guid: 57d4a6e606848364c9880f2adec16d90, type: 2}
propertyPath: m_LocalPosition.z
value: 10
objectReference: {fileID: 0}
- target: {fileID: 4000012948588652, guid: 57d4a6e606848364c9880f2adec16d90, type: 2}
propertyPath: m_LocalRotation.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 4000012948588652, guid: 57d4a6e606848364c9880f2adec16d90, type: 2}
propertyPath: m_LocalRotation.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 4000012948588652, guid: 57d4a6e606848364c9880f2adec16d90, type: 2}
propertyPath: m_LocalRotation.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 4000012948588652, guid: 57d4a6e606848364c9880f2adec16d90, type: 2}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: 4000012948588652, guid: 57d4a6e606848364c9880f2adec16d90, type: 2}
propertyPath: m_RootOrder
value: 2
objectReference: {fileID: 0}
- target: {fileID: 23000013406986662, guid: 57d4a6e606848364c9880f2adec16d90,
type: 2}
propertyPath: m_Materials.Array.data[0]
value:
objectReference: {fileID: 2100000, guid: 596fd740aeeee0d4cb4f962d4072954e, type: 2}
- target: {fileID: 114000010662012988, guid: 57d4a6e606848364c9880f2adec16d90,
type: 2}
propertyPath: m_Enabled
value: 1
objectReference: {fileID: 0}
m_RemovedComponents: []
m_ParentPrefab: {fileID: 100100000, guid: 57d4a6e606848364c9880f2adec16d90, type: 2}
m_RootGameObject: {fileID: 913398332}
m_IsPrefabParent: 0
--- !u!1 &1738296145
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_Component:
- component: {fileID: 1738296147}
- component: {fileID: 1738296146}
m_Layer: 0
m_Name: Directional Light
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!108 &1738296146
Light:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1738296145}
m_Enabled: 1
serializedVersion: 8
m_Type: 1
m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
m_Intensity: 1
m_Range: 10
m_SpotAngle: 30
m_CookieSize: 10
m_Shadows:
m_Type: 2
m_Resolution: -1
m_CustomResolution: -1
m_Strength: 1
m_Bias: 0.05
m_NormalBias: 0.4
m_NearPlane: 0.2
m_Cookie: {fileID: 0}
m_DrawHalo: 0
m_Flare: {fileID: 0}
m_RenderMode: 0
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_Lightmapping: 4
m_AreaSize: {x: 1, y: 1}
m_BounceIntensity: 1
m_FalloffTable:
m_Table[0]: 0
m_Table[1]: 0
m_Table[2]: 0
m_Table[3]: 0
m_Table[4]: 0
m_Table[5]: 0
m_Table[6]: 0
m_Table[7]: 0
m_Table[8]: 0
m_Table[9]: 0
m_Table[10]: 0
m_Table[11]: 0
m_Table[12]: 0
m_ColorTemperature: 6570
m_UseColorTemperature: 0
m_ShadowRadius: 0
m_ShadowAngle: 0
--- !u!4 &1738296147
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1738296145}
m_LocalRotation: {x: 0.40821794, y: -0.23456973, z: 0.109381676, w: 0.87542605}
m_LocalPosition: {x: 0, y: 3, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4e1efec2c71c5b94e8522880dd9636c8
timeCreated: 1480074355
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,512 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
OcclusionCullingSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: 0.25
backfaceThreshold: 100
m_SceneGUID: 00000000000000000000000000000000
m_OcclusionCullingData: {fileID: 0}
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 8
m_Fog: 0
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
m_FogMode: 3
m_FogDensity: 0.01
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 0
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
m_HaloStrength: 0.5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 11
m_GIWorkflowMode: 0
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_TemporalCoherenceThreshold: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 1
m_LightmapEditorSettings:
serializedVersion: 9
m_Resolution: 2
m_BakeResolution: 40
m_TextureWidth: 1024
m_TextureHeight: 1024
m_AO: 0
m_AOMaxDistance: 1
m_CompAOExponent: 1
m_CompAOExponentDirect: 0
m_Padding: 2
m_LightmapParameters: {fileID: 0}
m_LightmapsBakeMode: 1
m_TextureCompression: 1
m_FinalGather: 0
m_FinalGatherFiltering: 1
m_FinalGatherRayCount: 256
m_ReflectionCompression: 2
m_MixedBakeMode: 1
m_BakeBackend: 0
m_PVRSampling: 1
m_PVRDirectSampleCount: 32
m_PVRSampleCount: 500
m_PVRBounces: 2
m_PVRFiltering: 0
m_PVRFilteringMode: 1
m_PVRCulling: 1
m_PVRFilteringGaussRadiusDirect: 1
m_PVRFilteringGaussRadiusIndirect: 5
m_PVRFilteringGaussRadiusAO: 2
m_PVRFilteringAtrousColorSigma: 1
m_PVRFilteringAtrousNormalSigma: 1
m_PVRFilteringAtrousPositionSigma: 1
m_LightingDataAsset: {fileID: 0}
m_UseShadowmask: 0
--- !u!196 &4
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 2
agentTypeID: 0
agentRadius: 0.5
agentHeight: 2
agentSlope: 45
agentClimb: 0.4
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
minRegionArea: 2
manualCellSize: 0
cellSize: 0.16666667
manualTileSize: 0
tileSize: 256
accuratePlacement: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &129126780
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_Component:
- component: {fileID: 129126782}
- component: {fileID: 129126781}
m_Layer: 0
m_Name: Directional Light
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!108 &129126781
Light:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 129126780}
m_Enabled: 1
serializedVersion: 8
m_Type: 1
m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
m_Intensity: 1
m_Range: 10
m_SpotAngle: 30
m_CookieSize: 10
m_Shadows:
m_Type: 2
m_Resolution: -1
m_CustomResolution: -1
m_Strength: 1
m_Bias: 0.05
m_NormalBias: 0.4
m_NearPlane: 0.2
m_Cookie: {fileID: 0}
m_DrawHalo: 0
m_Flare: {fileID: 0}
m_RenderMode: 0
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_Lightmapping: 4
m_AreaSize: {x: 1, y: 1}
m_BounceIntensity: 1
m_FalloffTable:
m_Table[0]: 0
m_Table[1]: 0
m_Table[2]: 0
m_Table[3]: 0
m_Table[4]: 0
m_Table[5]: 0
m_Table[6]: 0
m_Table[7]: 0
m_Table[8]: 0
m_Table[9]: 0
m_Table[10]: 0
m_Table[11]: 0
m_Table[12]: 0
m_ColorTemperature: 6570
m_UseColorTemperature: 0
m_ShadowRadius: 0
m_ShadowAngle: 0
--- !u!4 &129126782
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 129126780}
m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
m_LocalPosition: {x: 0, y: 3, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
--- !u!1 &913398332
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 1000012642892690, guid: de6f36e446e5e8a48bf61fe198985bb4,
type: 2}
m_PrefabInternal: {fileID: 940835900}
serializedVersion: 5
m_Component:
- component: {fileID: 913398335}
- component: {fileID: 913398334}
- component: {fileID: 913398333}
- component: {fileID: 1426812830}
m_Layer: 0
m_Name: Monitor Board
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!23 &913398333
MeshRenderer:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 23000011974915108, guid: de6f36e446e5e8a48bf61fe198985bb4,
type: 2}
m_PrefabInternal: {fileID: 940835900}
m_GameObject: {fileID: 913398332}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: c181d333a7bee7a44b94c0f4e02c4bd4, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_PreserveUVs: 1
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
--- !u!33 &913398334
MeshFilter:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 33000012841683532, guid: de6f36e446e5e8a48bf61fe198985bb4,
type: 2}
m_PrefabInternal: {fileID: 940835900}
m_GameObject: {fileID: 913398332}
m_Mesh: {fileID: 4300002, guid: d6b30b913257fee4d8246bf7a2620fcd, type: 3}
--- !u!4 &913398335
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 4000011474108562, guid: de6f36e446e5e8a48bf61fe198985bb4,
type: 2}
m_PrefabInternal: {fileID: 940835900}
m_GameObject: {fileID: 913398332}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 10}
m_LocalScale: {x: 1.92, y: 1.08, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1001 &940835900
Prefab:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications:
- target: {fileID: 4000011474108562, guid: de6f36e446e5e8a48bf61fe198985bb4, type: 2}
propertyPath: m_LocalPosition.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 4000011474108562, guid: de6f36e446e5e8a48bf61fe198985bb4, type: 2}
propertyPath: m_LocalPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 4000011474108562, guid: de6f36e446e5e8a48bf61fe198985bb4, type: 2}
propertyPath: m_LocalPosition.z
value: 10
objectReference: {fileID: 0}
- target: {fileID: 4000011474108562, guid: de6f36e446e5e8a48bf61fe198985bb4, type: 2}
propertyPath: m_LocalRotation.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 4000011474108562, guid: de6f36e446e5e8a48bf61fe198985bb4, type: 2}
propertyPath: m_LocalRotation.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 4000011474108562, guid: de6f36e446e5e8a48bf61fe198985bb4, type: 2}
propertyPath: m_LocalRotation.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 4000011474108562, guid: de6f36e446e5e8a48bf61fe198985bb4, type: 2}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: 4000011474108562, guid: de6f36e446e5e8a48bf61fe198985bb4, type: 2}
propertyPath: m_RootOrder
value: 2
objectReference: {fileID: 0}
m_RemovedComponents: []
m_ParentPrefab: {fileID: 100100000, guid: de6f36e446e5e8a48bf61fe198985bb4, type: 2}
m_RootGameObject: {fileID: 913398332}
m_IsPrefabParent: 0
--- !u!1 &1324913475
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_Component:
- component: {fileID: 1324913479}
- component: {fileID: 1324913478}
- component: {fileID: 1324913477}
- component: {fileID: 1324913476}
- component: {fileID: 1324913480}
m_Layer: 0
m_Name: GetPixels() Plane
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!23 &1324913476
MeshRenderer:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1324913475}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_PreserveUVs: 1
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
--- !u!64 &1324913477
MeshCollider:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1324913475}
m_Material: {fileID: 0}
m_IsTrigger: 0
m_Enabled: 1
serializedVersion: 2
m_Convex: 0
m_InflateMesh: 0
m_SkinWidth: 0.01
m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0}
--- !u!33 &1324913478
MeshFilter:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1324913475}
m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0}
--- !u!4 &1324913479
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1324913475}
m_LocalRotation: {x: 0, y: -0.7071068, z: 0.7071068, w: 0}
m_LocalPosition: {x: 11, y: 4, z: 10}
m_LocalScale: {x: 0.25, y: 1, z: 0.25}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 90, y: 0, z: 180}
--- !u!114 &1324913480
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1324913475}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fd3f838ff57152e44a1810274a9df49b, type: 3}
m_Name:
m_EditorClassIdentifier:
uddTexture: {fileID: 1426812830}
x: 100
y: 100
texture: {fileID: 0}
--- !u!114 &1426812830
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 114000012274256594, guid: de6f36e446e5e8a48bf61fe198985bb4,
type: 2}
m_PrefabInternal: {fileID: 940835900}
m_GameObject: {fileID: 913398332}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: bb54a34570e4747429b1c5b66c69d356, type: 3}
m_Name:
m_EditorClassIdentifier:
invertX_: 0
invertY_: 0
useClip_: 0
clipPos: {x: 0, y: 0}
clipScale: {x: 0.2, y: 0.2}
--- !u!1 &1446288312
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_Component:
- component: {fileID: 1446288317}
- component: {fileID: 1446288316}
- component: {fileID: 1446288315}
- component: {fileID: 1446288314}
- component: {fileID: 1446288313}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!81 &1446288313
AudioListener:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1446288312}
m_Enabled: 1
--- !u!124 &1446288314
Behaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1446288312}
m_Enabled: 1
--- !u!92 &1446288315
Behaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1446288312}
m_Enabled: 1
--- !u!20 &1446288316
Camera:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1446288312}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 1
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: 0.3
far clip plane: 1000
field of view: 60
orthographic: 0
orthographic size: 5
m_Depth: -1
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 0
m_AllowMSAA: 1
m_ForceIntoRT: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: 0.022
m_StereoMirrorMode: 0
--- !u!4 &1446288317
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1446288312}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 1, z: -10}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 38a5db360d5147c46ae925104162b881
timeCreated: 1480420198
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,403 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
OcclusionCullingSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: 0.25
backfaceThreshold: 100
m_SceneGUID: 00000000000000000000000000000000
m_OcclusionCullingData: {fileID: 0}
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 8
m_Fog: 0
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
m_FogMode: 3
m_FogDensity: 0.01
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 0
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
m_HaloStrength: 0.5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 11
m_GIWorkflowMode: 0
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_TemporalCoherenceThreshold: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 1
m_LightmapEditorSettings:
serializedVersion: 9
m_Resolution: 2
m_BakeResolution: 40
m_TextureWidth: 1024
m_TextureHeight: 1024
m_AO: 0
m_AOMaxDistance: 1
m_CompAOExponent: 1
m_CompAOExponentDirect: 0
m_Padding: 2
m_LightmapParameters: {fileID: 0}
m_LightmapsBakeMode: 1
m_TextureCompression: 1
m_FinalGather: 0
m_FinalGatherFiltering: 1
m_FinalGatherRayCount: 256
m_ReflectionCompression: 2
m_MixedBakeMode: 1
m_BakeBackend: 0
m_PVRSampling: 1
m_PVRDirectSampleCount: 32
m_PVRSampleCount: 500
m_PVRBounces: 2
m_PVRFiltering: 0
m_PVRFilteringMode: 1
m_PVRCulling: 1
m_PVRFilteringGaussRadiusDirect: 1
m_PVRFilteringGaussRadiusIndirect: 5
m_PVRFilteringGaussRadiusAO: 2
m_PVRFilteringAtrousColorSigma: 1
m_PVRFilteringAtrousNormalSigma: 1
m_PVRFilteringAtrousPositionSigma: 1
m_LightingDataAsset: {fileID: 0}
m_UseShadowmask: 0
--- !u!196 &4
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 2
agentTypeID: 0
agentRadius: 0.5
agentHeight: 2
agentSlope: 45
agentClimb: 0.4
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
minRegionArea: 2
manualCellSize: 0
cellSize: 0.16666667
manualTileSize: 0
tileSize: 256
accuratePlacement: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &240701085
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 1000012642892690, guid: de6f36e446e5e8a48bf61fe198985bb4,
type: 2}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_Component:
- component: {fileID: 240701092}
- component: {fileID: 240701091}
- component: {fileID: 240701090}
- component: {fileID: 240701089}
- component: {fileID: 240701087}
- component: {fileID: 240701086}
m_Layer: 0
m_Name: Monitor
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &240701086
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 240701085}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 52d402bdca823cc42925c9d65993ee59, type: 3}
m_Name:
m_EditorClassIdentifier:
calcAveragePos: 1
moveRectFilter: 0.05
mouseFilter: 0.05
dirtyRectFilter: 0.025
noEventFilter: 0.05
velocityFilter: 0.1
drawAveragePos: 1
drawCursorPos: 0
drawMoveRects: 1
drawDirtyRects: 1
--- !u!114 &240701087
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 240701085}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 602d3a9bed585d14eaf21e0528d24d54, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &240701089
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 114000012274256594, guid: de6f36e446e5e8a48bf61fe198985bb4,
type: 2}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 240701085}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: bb54a34570e4747429b1c5b66c69d356, type: 3}
m_Name:
m_EditorClassIdentifier:
invertX_: 0
invertY_: 0
useClip_: 0
clipPos: {x: 0, y: 0}
clipScale: {x: 0.2, y: 0.2}
--- !u!23 &240701090
MeshRenderer:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 23000011974915108, guid: de6f36e446e5e8a48bf61fe198985bb4,
type: 2}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 240701085}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: c181d333a7bee7a44b94c0f4e02c4bd4, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_PreserveUVs: 1
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
--- !u!33 &240701091
MeshFilter:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 33000012841683532, guid: de6f36e446e5e8a48bf61fe198985bb4,
type: 2}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 240701085}
m_Mesh: {fileID: 4300002, guid: d6b30b913257fee4d8246bf7a2620fcd, type: 3}
--- !u!4 &240701092
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 4000011474108562, guid: de6f36e446e5e8a48bf61fe198985bb4,
type: 2}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 240701085}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 10}
m_LocalScale: {x: 1.92, y: 1.08, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &772447740
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_Component:
- component: {fileID: 772447742}
- component: {fileID: 772447741}
m_Layer: 0
m_Name: Directional Light
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!108 &772447741
Light:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 772447740}
m_Enabled: 1
serializedVersion: 8
m_Type: 1
m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
m_Intensity: 1
m_Range: 10
m_SpotAngle: 30
m_CookieSize: 10
m_Shadows:
m_Type: 2
m_Resolution: -1
m_CustomResolution: -1
m_Strength: 1
m_Bias: 0.05
m_NormalBias: 0.4
m_NearPlane: 0.2
m_Cookie: {fileID: 0}
m_DrawHalo: 0
m_Flare: {fileID: 0}
m_RenderMode: 0
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_Lightmapping: 4
m_AreaSize: {x: 1, y: 1}
m_BounceIntensity: 1
m_FalloffTable:
m_Table[0]: 0
m_Table[1]: 0
m_Table[2]: 0
m_Table[3]: 0
m_Table[4]: 0
m_Table[5]: 0
m_Table[6]: 0
m_Table[7]: 0
m_Table[8]: 0
m_Table[9]: 0
m_Table[10]: 0
m_Table[11]: 0
m_Table[12]: 0
m_ColorTemperature: 6570
m_UseColorTemperature: 0
m_ShadowRadius: 0
m_ShadowAngle: 0
--- !u!4 &772447742
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 772447740}
m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
m_LocalPosition: {x: 0, y: 3, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
--- !u!1 &1789105689
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_Component:
- component: {fileID: 1789105694}
- component: {fileID: 1789105693}
- component: {fileID: 1789105692}
- component: {fileID: 1789105691}
- component: {fileID: 1789105690}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!81 &1789105690
AudioListener:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1789105689}
m_Enabled: 1
--- !u!124 &1789105691
Behaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1789105689}
m_Enabled: 1
--- !u!92 &1789105692
Behaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1789105689}
m_Enabled: 1
--- !u!20 &1789105693
Camera:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1789105689}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 1
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: 0.3
far clip plane: 1000
field of view: 60
orthographic: 0
orthographic size: 5
m_Depth: -1
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 0
m_AllowMSAA: 1
m_ForceIntoRT: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: 0.022
m_StereoMirrorMode: 0
--- !u!4 &1789105694
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1789105689}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: -3}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: aac40d1b58f3f8940be815779d89b5a4
timeCreated: 1479544409
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,466 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
OcclusionCullingSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: 0.25
backfaceThreshold: 100
m_SceneGUID: 00000000000000000000000000000000
m_OcclusionCullingData: {fileID: 0}
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 8
m_Fog: 0
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
m_FogMode: 3
m_FogDensity: 0.01
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 0
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
m_HaloStrength: 0.5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 11
m_GIWorkflowMode: 0
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_TemporalCoherenceThreshold: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 1
m_LightmapEditorSettings:
serializedVersion: 9
m_Resolution: 2
m_BakeResolution: 40
m_TextureWidth: 1024
m_TextureHeight: 1024
m_AO: 0
m_AOMaxDistance: 1
m_CompAOExponent: 0
m_CompAOExponentDirect: 0
m_Padding: 2
m_LightmapParameters: {fileID: 0}
m_LightmapsBakeMode: 1
m_TextureCompression: 1
m_FinalGather: 0
m_FinalGatherFiltering: 1
m_FinalGatherRayCount: 1024
m_ReflectionCompression: 2
m_MixedBakeMode: 1
m_BakeBackend: 0
m_PVRSampling: 1
m_PVRDirectSampleCount: 32
m_PVRSampleCount: 500
m_PVRBounces: 2
m_PVRFiltering: 0
m_PVRFilteringMode: 1
m_PVRCulling: 1
m_PVRFilteringGaussRadiusDirect: 1
m_PVRFilteringGaussRadiusIndirect: 5
m_PVRFilteringGaussRadiusAO: 2
m_PVRFilteringAtrousColorSigma: 1
m_PVRFilteringAtrousNormalSigma: 1
m_PVRFilteringAtrousPositionSigma: 1
m_LightingDataAsset: {fileID: 0}
m_UseShadowmask: 0
--- !u!196 &4
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 2
agentTypeID: 0
agentRadius: 0.5
agentHeight: 2
agentSlope: 45
agentClimb: 0.4
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
minRegionArea: 2
manualCellSize: 0
cellSize: 0.16666667
manualTileSize: 0
tileSize: 256
accuratePlacement: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &79264388
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_Component:
- component: {fileID: 79264393}
- component: {fileID: 79264392}
- component: {fileID: 79264391}
- component: {fileID: 79264390}
- component: {fileID: 79264389}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!81 &79264389
AudioListener:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 79264388}
m_Enabled: 1
--- !u!124 &79264390
Behaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 79264388}
m_Enabled: 1
--- !u!92 &79264391
Behaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 79264388}
m_Enabled: 1
--- !u!20 &79264392
Camera:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 79264388}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 1
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0.019607844}
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: 0.3
far clip plane: 1000
field of view: 60
orthographic: 0
orthographic size: 5
m_Depth: -1
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 0
m_AllowMSAA: 1
m_ForceIntoRT: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: 0.022
m_StereoMirrorMode: 0
--- !u!4 &79264393
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 79264388}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: -6}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &400296148
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_Component:
- component: {fileID: 400296150}
- component: {fileID: 400296149}
- component: {fileID: 400296151}
- component: {fileID: 400296152}
m_Layer: 0
m_Name: Multiple Monitor Creator
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &400296149
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 400296148}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fb22986017201f74aa864dcbf0cab751, type: 3}
m_Name:
m_EditorClassIdentifier:
monitorPrefab: {fileID: 1000012642892690, guid: de6f36e446e5e8a48bf61fe198985bb4,
type: 2}
scaleMode: 1
scale: 0.3
meshForwardDirection: 1
removeIfUnsupported: 1
removeWaitDuration: 15
removeChildrenWhenClear: 1
--- !u!4 &400296150
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 400296148}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 3}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &400296151
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 400296148}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: a31b05fdfa301f14e88365e64622b43a, type: 3}
m_Name:
m_EditorClassIdentifier:
updateEveryFrame: 1
margin: 0.1
thickness: 1
debugDraw: 1
radius: 5
offsetAngle: {x: 0, y: 0, z: 0}
--- !u!114 &400296152
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 400296148}
m_Enabled: 0
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: dbdfccef47068644b81b671bb4e6e166, type: 3}
m_Name:
m_EditorClassIdentifier:
gazePointFilter: 0.03
moveRectFilter: 0.05
mouseFilter: 0.05
dirtyRectFilter: 0.01
noEventFilter: 0.01
velocityFilter: 0.1
drawGazePoint: 1
drawAveragePos: 1
drawMoveRects: 1
drawDirtyRects: 1
--- !u!1 &1070915829
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_Component:
- component: {fileID: 1070915830}
m_Layer: 0
m_Name: To
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &1070915830
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1070915829}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: -2.41, y: 0, z: 3.36}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 1470035823}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1470035821
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_Component:
- component: {fileID: 1470035823}
- component: {fileID: 1470035822}
m_Layer: 0
m_Name: Ray Tester
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &1470035822
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1470035821}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 810a4ad59c7d8d34e9b6014e8191fffe, type: 3}
m_Name:
m_EditorClassIdentifier:
from: {fileID: 1976533531}
to: {fileID: 1070915830}
--- !u!4 &1470035823
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1470035821}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: -0.27}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 1976533531}
- {fileID: 1070915830}
m_Father: {fileID: 0}
m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1738296145
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_Component:
- component: {fileID: 1738296147}
- component: {fileID: 1738296146}
m_Layer: 0
m_Name: Directional Light
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!108 &1738296146
Light:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1738296145}
m_Enabled: 1
serializedVersion: 8
m_Type: 1
m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
m_Intensity: 1
m_Range: 10
m_SpotAngle: 30
m_CookieSize: 10
m_Shadows:
m_Type: 2
m_Resolution: -1
m_CustomResolution: -1
m_Strength: 1
m_Bias: 0.05
m_NormalBias: 0.4
m_NearPlane: 0.2
m_Cookie: {fileID: 0}
m_DrawHalo: 0
m_Flare: {fileID: 0}
m_RenderMode: 0
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_Lightmapping: 4
m_AreaSize: {x: 1, y: 1}
m_BounceIntensity: 1
m_FalloffTable:
m_Table[0]: 0
m_Table[1]: 0
m_Table[2]: 0
m_Table[3]: 0
m_Table[4]: 0
m_Table[5]: 0
m_Table[6]: 0
m_Table[7]: 0
m_Table[8]: 0
m_Table[9]: 0
m_Table[10]: 0
m_Table[11]: 0
m_Table[12]: 0
m_ColorTemperature: 6570
m_UseColorTemperature: 0
m_ShadowRadius: 0
m_ShadowAngle: 0
--- !u!4 &1738296147
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1738296145}
m_LocalRotation: {x: 0.40821794, y: -0.23456973, z: 0.109381676, w: 0.87542605}
m_LocalPosition: {x: 0, y: 3, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1976533530
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_Component:
- component: {fileID: 1976533531}
m_Layer: 0
m_Name: From
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &1976533531
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1976533530}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 1.89, y: 0, z: -4.58}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 1470035823}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f68bd0626da87264cb4daca57d3c1594
timeCreated: 1481736541
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,58 @@
using UnityEngine;
using UnityEngine.Assertions;
[RequireComponent(typeof(uDesktopDuplication.Texture))]
public class DisplacementMapping : MonoBehaviour
{
public enum TargetMonitor
{
Self,
Next,
Prev,
}
public TargetMonitor target = TargetMonitor.Self;
uDesktopDuplication.Texture uddTexture_;
int dispTexId_;
int dispFactorId_;
int tessMinDistId_;
int tessMaxDistId_;
int tessFactorId_;
[Range(0.0f, 10f)] public float displacementFactor = 0.1f;
[Range(0.1f, 10f)] public float tessellationMinDist = 0.5f;
[Range(1.0f, 50f)] public float tessellationMaxDist = 25f;
[Range(1.0f, 50f)] public float tessellationFactor = 25f;
void Start()
{
uddTexture_ = GetComponent<uDesktopDuplication.Texture>();
Assert.IsNotNull(uddTexture_);
dispTexId_ = Shader.PropertyToID("_DispTex");
dispFactorId_ = Shader.PropertyToID("_DispFactor");
tessMinDistId_ = Shader.PropertyToID("_TessMinDist");
tessMaxDistId_ = Shader.PropertyToID("_TessMaxDist");
tessFactorId_ = Shader.PropertyToID("_TessFactor");
}
void Update()
{
var id = uddTexture_.monitor.id;
switch (target) {
case TargetMonitor.Self: break;
case TargetMonitor.Next: ++id; break;
case TargetMonitor.Prev: --id; break;
}
id = Mathf.Clamp(id, 0, uDesktopDuplication.Manager.monitorCount - 1);
var monitor = uDesktopDuplication.Manager.GetMonitor(id);
monitor.shouldBeUpdated = true;
uddTexture_.material.SetTexture(dispTexId_, monitor.texture);
uddTexture_.material.SetFloat(dispFactorId_, displacementFactor);
uddTexture_.material.SetFloat(tessMinDistId_, tessellationMinDist);
uddTexture_.material.SetFloat(tessMaxDistId_, tessellationMaxDist);
uddTexture_.material.SetFloat(tessFactorId_, tessellationFactor);
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 859a2446b86e55c43932212872c82748
timeCreated: 1480146517
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,168 @@
using UnityEngine;
using MeshForwardDirection = uDesktopDuplication.Texture.MeshForwardDirection;
[RequireComponent(typeof(uDesktopDuplication.Texture))]
public class GazePointAnalyzer : MonoBehaviour
{
uDesktopDuplication.Texture uddTexture_;
[Tooltip("This needs a small calculation cost.")]
public bool calcAveragePos = true;
private Vector2 averageCoord_ = Vector2.zero;
private Vector2 averageCoordVelocity_ = Vector2.zero;
public Vector3 averagePos
{
get { return GetWorldPositionFromCoord((int)averageCoord_.x, (int)averageCoord_.y); }
}
public Vector3 cursorPos
{
get { return GetWorldPositionFromCoord(uddTexture_.monitor.cursorX, uddTexture_.monitor.cursorY); }
}
private Vector2 preCursorCoord_ = Vector2.zero;
[Header("Filters")]
[Range(0f, 1f)] public float moveRectFilter = 0.05f;
[Range(0f, 1f)] public float mouseFilter = 0.05f;
[Range(0f, 1f)] public float dirtyRectFilter = 0.01f;
[Range(0f, 1f)] public float noEventFilter = 0.01f;
[Range(0f, 1f)] public float velocityFilter = 0.1f;
[Header("Debug")]
public bool drawAveragePos;
public bool drawCursorPos;
public bool drawMoveRects;
public bool drawDirtyRects;
void Start()
{
uddTexture_ = GetComponent<uDesktopDuplication.Texture>();
averageCoord_ = new Vector2(uddTexture_.monitor.width / 2, uddTexture_.monitor.height / 2);
}
public Vector3 GetWorldPositionFromCoord(int u, int v)
{
return uddTexture_.GetWorldPositionFromCoord(u, v);
}
void CalcAveragePos()
{
if (!calcAveragePos) return;
var coord = Vector2.zero;
var monitor = uddTexture_.monitor;
var cursorCoord = new Vector2(monitor.cursorX, monitor.cursorY);
var filter = 0f;
// move rect
if (monitor.moveRectCount > 0) {
foreach (var rects in monitor.moveRects) {
var rect = rects.destination;
var center = new Vector2(
(rect.right + rect.left) / 2,
(rect.bottom + rect.top) / 2);
coord += center;
}
coord /= monitor.moveRectCount;
filter = moveRectFilter;
}
// mouse
else if (
monitor.isCursorVisible &&
cursorCoord != preCursorCoord_ &&
(cursorCoord - preCursorCoord_).magnitude > 5 &&
monitor.cursorX >= 0 &&
monitor.cursorY >= 0)
{
coord = cursorCoord;
filter = mouseFilter;
}
// dirty rect
else if (monitor.dirtyRectCount > 0) {
var totalWeights = 0f;
foreach (var rect in monitor.dirtyRects) {
var center = new Vector2(
(rect.right + rect.left) / 2,
(rect.bottom + rect.top) / 2);
var weight = 1f / Mathf.Sqrt((rect.right - rect.left) * (rect.bottom - rect.top));
coord += center * weight;
totalWeights += weight;
}
coord /= totalWeights;
filter = dirtyRectFilter;
}
// no event
else {
coord = new Vector2(monitor.width / 2, monitor.height / 2);
filter = noEventFilter;
}
var cf = (filter / ((1f / 60) / Time.deltaTime));
var vf = (velocityFilter / ((1f / 60) / Time.deltaTime));
var targetCoord = averageCoord_ + (coord - averageCoord_) * cf;
var targetVelocity = targetCoord - averageCoord_;
if (float.IsNaN(targetCoord.x) || float.IsNaN(targetCoord.y)) return;
if (float.IsNaN(targetVelocity.x) || float.IsNaN(targetVelocity.y)) return;
averageCoordVelocity_ += (targetVelocity - averageCoordVelocity_) * vf;
averageCoord_ += averageCoordVelocity_;
averageCoord_.x = Mathf.Clamp(averageCoord_.x, 0, monitor.width);
averageCoord_.y = Mathf.Clamp(averageCoord_.y, 0, monitor.height);
preCursorCoord_ = cursorCoord;
}
void Update()
{
CalcAveragePos();
DebugDraw();
}
void DebugDraw()
{
if (drawAveragePos) DrawAveragePos();
if (drawCursorPos) DrawCursorPos();
if (drawDirtyRects) DrawDirtyRects();
if (drawMoveRects) DrawMoveRects();
}
void DrawRect(uDesktopDuplication.RECT rect, Color color)
{
var p0 = GetWorldPositionFromCoord(rect.left, rect.top);
var p1 = GetWorldPositionFromCoord(rect.right, rect.top);
var p2 = GetWorldPositionFromCoord(rect.right, rect.bottom);
var p3 = GetWorldPositionFromCoord(rect.left, rect.bottom);
Debug.DrawLine(p0, p1, color);
Debug.DrawLine(p1, p2, color);
Debug.DrawLine(p2, p3, color);
Debug.DrawLine(p3, p0, color);
}
void DrawAveragePos()
{
Debug.DrawLine(transform.position, averagePos, Color.yellow);
}
void DrawCursorPos()
{
Debug.DrawLine(transform.position, cursorPos, Color.grey);
}
void DrawMoveRects()
{
foreach (var rect in uddTexture_.monitor.moveRects) {
DrawRect(rect.source, Color.blue);
DrawRect(rect.destination, Color.green);
}
}
void DrawDirtyRects()
{
foreach (var rect in uddTexture_.monitor.dirtyRects) {
DrawRect(rect, Color.red);
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 52d402bdca823cc42925c9d65993ee59
timeCreated: 1479546123
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,36 @@
using UnityEngine;
public class GetPixelsExample : MonoBehaviour
{
[SerializeField] uDesktopDuplication.Texture uddTexture;
[SerializeField] int x = 100;
[SerializeField] int y = 100;
const int width = 64;
const int height = 32;
public Texture2D texture;
Color32[] colors = new Color32[width * height];
void Start()
{
texture = new Texture2D(width, height, TextureFormat.ARGB32, false);
GetComponent<Renderer>().material.mainTexture = texture;
}
void Update()
{
// must be called (performance will be slightly down).
uDesktopDuplication.Manager.primary.useGetPixels = true;
var monitor = uddTexture.monitor;
if (!monitor.hasBeenUpdated) return;
if (monitor.GetPixels(colors, x, y, width, height)) {
texture.SetPixels32(colors);
texture.Apply();
}
Debug.Log(monitor.GetPixel(monitor.cursorX, monitor.cursorY));
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: fd3f838ff57152e44a1810274a9df49b
timeCreated: 1480420430
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,5 +1,6 @@
using UnityEngine;
[RequireComponent(typeof(uDesktopDuplication.Texture))]
public class Loupe : MonoBehaviour
{
private uDesktopDuplication.Texture uddTexture_;
@@ -12,7 +13,7 @@ public class Loupe : MonoBehaviour
uddTexture_.useClip = true;
}
void Update()
void LateUpdate()
{
CheckVariables();
@@ -26,11 +27,12 @@ public class Loupe : MonoBehaviour
}
var monitor = uddTexture_.monitor;
var cursorX = monitor.isCursorVisible ? monitor.cursorX : monitor.systemCursorX;
var cursorY = monitor.isCursorVisible ? monitor.cursorY : monitor.systemCursorY;
var x = (float)cursorX / monitor.width;
var y = (float)cursorY / monitor.height;
var x = monitor.isCursorVisible ?
(float)monitor.cursorX / monitor.width :
(float)monitor.systemCursorX / monitor.width;
var y = monitor.isCursorVisible ?
(float)monitor.cursorY / monitor.height :
(float)monitor.systemCursorY / monitor.height;
var w = 1f / zoom;
var h = w / aspect * monitor.aspect;
x = Mathf.Clamp(x - w / 2, 0f, 1f - w);
@@ -40,7 +42,7 @@ public class Loupe : MonoBehaviour
}
void CheckVariables()
{
{
if (zoom < 1f) zoom = 1f;
if (aspect < 0.01f) aspect = 0.01f;
}

View File

@@ -0,0 +1,69 @@
using UnityEngine;
[RequireComponent(typeof(MultipleMonitorCreator))]
public class MultipleMonitorAnalyzer : MonoBehaviour
{
MultipleMonitorCreator creator_;
Vector3 gazePoint_ = Vector3.zero;
public Vector3 gazePoint
{
get { return gazePoint_; }
private set
{
gazePoint_ += (value - gazePoint) * (gazePointFilter / (1f / 60 / Time.deltaTime));
}
}
[Header("Filters")]
[Range(0f, 1f)] public float gazePointFilter = 0.1f;
[Range(0f, 1f)] public float moveRectFilter = 0.05f;
[Range(0f, 1f)] public float mouseFilter = 0.05f;
[Range(0f, 1f)] public float dirtyRectFilter = 0.01f;
[Range(0f, 1f)] public float noEventFilter = 0.01f;
[Range(0f, 1f)] public float velocityFilter = 0.1f;
[Header("Debug")]
[SerializeField] bool drawGazePoint;
[SerializeField] bool drawAveragePos;
[SerializeField] bool drawMoveRects;
[SerializeField] bool drawDirtyRects;
void Start()
{
creator_ = GetComponent<MultipleMonitorCreator>();
}
void Update()
{
var cursorMonitorId = uDesktopDuplication.Manager.cursorMonitorId;
for (int i = 0; i < creator_.monitors.Count; ++i) {
var info = creator_.monitors[i];
var analyzer =
info.gameObject.GetComponent<GazePointAnalyzer>() ??
info.gameObject.AddComponent<GazePointAnalyzer>();
UpdateAnalyzer(analyzer);
if (info.uddTexture.monitorId == cursorMonitorId) {
gazePoint = analyzer.averagePos;
}
}
if (drawGazePoint) DrawGazePoint();
}
void DrawGazePoint()
{
Debug.DrawLine(transform.position, gazePoint, Color.magenta);
}
void UpdateAnalyzer(GazePointAnalyzer analyzer)
{
analyzer.moveRectFilter = moveRectFilter;
analyzer.mouseFilter = mouseFilter;
analyzer.dirtyRectFilter = dirtyRectFilter;
analyzer.noEventFilter = noEventFilter;
analyzer.velocityFilter = velocityFilter;
analyzer.drawAveragePos = drawAveragePos;
analyzer.drawMoveRects = drawMoveRects;
analyzer.drawDirtyRects = drawDirtyRects;
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: dbdfccef47068644b81b671bb4e6e166
timeCreated: 1479620455
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,6 +1,8 @@
using UnityEngine;
using UnityEngine.Assertions;
using System.Collections.Generic;
using MeshForwardDirection = uDesktopDuplication.Texture.MeshForwardDirection;
using DuplicatorState = uDesktopDuplication.DuplicatorState;
public class MultipleMonitorCreator : MonoBehaviour
{
@@ -39,6 +41,7 @@ public class MultipleMonitorCreator : MonoBehaviour
{
public GameObject gameObject { get; set; }
public Quaternion originalRotation { get; set; }
public Vector3 originalLocalScale { get; set; }
public uDesktopDuplication.Texture uddTexture { get; set; }
public Mesh mesh { get; set; }
}
@@ -46,6 +49,15 @@ public class MultipleMonitorCreator : MonoBehaviour
private List<MonitorInfo> monitors_ = new List<MonitorInfo>();
public List<MonitorInfo> monitors { get { return monitors_; } }
public class SavedMonitorInfo
{
public float widthScale = 1f;
public float heightScale = 1f;
}
private List<SavedMonitorInfo> savedInfoList_ = new List<SavedMonitorInfo>();
public List<SavedMonitorInfo> savedInfoList { get { return savedInfoList_; } }
void Start()
{
uDesktopDuplication.Manager.CreateInstance();
@@ -79,12 +91,12 @@ public class MultipleMonitorCreator : MonoBehaviour
removeWaitTimer_ += Time.deltaTime;
if (removeWaitTimer_ > removeWaitDuration) {
hasMonitorUnsupportStateChecked_ = true;
foreach (var info in monitors_) {
if (info.uddTexture.monitor.state == uDesktopDuplication.MonitorState.Unsupported) {
foreach (var info in monitors) {
if (info.uddTexture.monitor.state == DuplicatorState.Unsupported) {
Destroy(info.gameObject);
}
}
monitors_.RemoveAll(info => info.uddTexture.monitor.state == uDesktopDuplication.MonitorState.Unsupported);
monitors.RemoveAll(info => info.uddTexture.monitor.state == DuplicatorState.Unsupported);
}
}
}
@@ -100,13 +112,21 @@ public class MultipleMonitorCreator : MonoBehaviour
ResetRemoveTimer();
// Create monitors
for (int i = 0; i < uDesktopDuplication.Manager.monitorCount; ++i) {
var n = uDesktopDuplication.Manager.monitors.Count;
for (int i = 0; i < n; ++i) {
// Create monitor obeject
var go = Instantiate(monitorPrefab);
go.name = "Monitor " + i;
go.name = uDesktopDuplication.Manager.monitors[i].name;
// Saved infomation
if (savedInfoList.Count == i) {
savedInfoList.Add(new SavedMonitorInfo());
Assert.AreEqual(i, savedInfoList.Count - 1);
}
var savedInfo = savedInfoList[i];
// Expand AABB
var mesh = go.GetComponent<MeshFilter>().sharedMesh;
var mesh = go.GetComponent<MeshFilter>().mesh; // clone
var aabbScale = mesh.bounds.size;
aabbScale.y = Mathf.Max(aabbScale.y, aabbScale.x);
aabbScale.z = Mathf.Max(aabbScale.z, aabbScale.x);
@@ -125,14 +145,18 @@ public class MultipleMonitorCreator : MonoBehaviour
height = monitor.heightMeter;
break;
case ScaleMode.Fixed:
width = scale * (monitor.isHorizontal ? 1f : monitor.aspect);
height = scale * (monitor.isHorizontal ? 1f / monitor.aspect : 1f);
width = scale * (monitor.isHorizontal ? monitor.aspect : 1f);
height = scale * (monitor.isHorizontal ? 1f : 1f / monitor.aspect);
break;
case ScaleMode.Pixel:
width = scale * (monitor.isHorizontal ? 1f : monitor.aspect) * ((float)monitor.width / 1920);
height = scale * (monitor.isHorizontal ? 1f / monitor.aspect : 1f) * ((float)monitor.width / 1920);
break;
}
width *= savedInfo.widthScale;
height *= savedInfo.heightScale;
if (meshForwardDirection == MeshForwardDirection.Y) {
go.transform.localScale = new Vector3(width, go.transform.localScale.y, height);
} else {
@@ -146,18 +170,19 @@ public class MultipleMonitorCreator : MonoBehaviour
var info = new MonitorInfo();
info.gameObject = go;
info.originalRotation = go.transform.rotation;
info.originalLocalScale = go.transform.localScale;
info.uddTexture = texture;
info.mesh = mesh;
monitors_.Add(info);
monitors.Add(info);
}
// Sort monitors in coordinate order
monitors_.Sort((a, b) => a.uddTexture.monitor.left - b.uddTexture.monitor.left);
monitors.Sort((a, b) => a.uddTexture.monitor.left - b.uddTexture.monitor.left);
}
void Clear()
{
foreach (var info in monitors_) {
foreach (var info in monitors) {
Destroy(info.gameObject);
}
if (removeChildrenWhenClear) {
@@ -165,7 +190,7 @@ public class MultipleMonitorCreator : MonoBehaviour
Destroy(transform.GetChild(i).gameObject);
}
}
monitors_.Clear();
monitors.Clear();
}
[ContextMenu("Recreate")]

View File

@@ -4,9 +4,9 @@
public class MultipleMonitorLayouter : MonoBehaviour
{
protected MultipleMonitorCreator creator_;
[SerializeField] bool updateEveryFrame = true;
[SerializeField] protected float margin = 0.1f;
[SerializeField][Range(0f, 10f)] protected float thickness = 1f;
public bool updateEveryFrame = true;
public float margin = 0.1f;
[Range(0f, 10f)] public float thickness = 1f;
void Start()
{
@@ -30,7 +30,7 @@ public class MultipleMonitorLayouter : MonoBehaviour
var totalWidth = 0f;
foreach (var info in monitors) {
var width = info.gameObject.transform.localEulerAngles.x * (info.mesh.bounds.extents.x * 2f);
var width = info.gameObject.transform.localScale.x * (info.mesh.bounds.extents.x * 2f);
totalWidth += width;
}
totalWidth += margin * (n - 1);
@@ -38,7 +38,7 @@ public class MultipleMonitorLayouter : MonoBehaviour
var x = -totalWidth / 2;
foreach (var info in monitors) {
var width = info.gameObject.transform.localEulerAngles.x;
var width = info.gameObject.transform.localScale.x;
x += (width * info.mesh.bounds.extents.x);
info.gameObject.transform.localPosition = new Vector3(x, 0f, 0f);
info.gameObject.transform.localRotation = info.originalRotation;

View File

@@ -1,7 +1,10 @@
using UnityEngine;
using MeshForwardDirection = uDesktopDuplication.Texture.MeshForwardDirection;
public class MultipleMonitorRoundLayouter : MultipleMonitorLayouter
{
[SerializeField] bool debugDraw = true;
public float radius = 10f;
public Vector3 offsetAngle = Vector3.zero;
@@ -17,6 +20,28 @@ public class MultipleMonitorRoundLayouter : MultipleMonitorLayouter
var monitors = creator_.monitors;
var n = monitors.Count;
// Keep the local scale z of monitors as 1 to bend them correctly.
// And save width / height to use same values after reinitialization.
for (int i = 0; i < n; ++i) {
var info = monitors[i];
var savedInfo = creator_.savedInfoList[i];
var scale = info.gameObject.transform.localScale;
if (creator_.meshForwardDirection == MeshForwardDirection.Y) {
scale.y = 1f;
savedInfo.widthScale = scale.x / info.originalLocalScale.x;
savedInfo.heightScale = scale.z / info.originalLocalScale.z;
} else {
scale.z = 1f;
savedInfo.widthScale = scale.x / info.originalLocalScale.x;
savedInfo.heightScale = scale.y / info.originalLocalScale.y;
}
info.gameObject.transform.localScale = scale;
}
// keep thicness plus value.
thickness = Mathf.Max(thickness, 0f);
// calculate total width
var totalWidth = 0f;
foreach (var info in monitors) {
var width = info.gameObject.transform.localScale.x * (info.mesh.bounds.extents.x * 2f);
@@ -24,9 +49,13 @@ public class MultipleMonitorRoundLayouter : MultipleMonitorLayouter
}
totalWidth += margin * (n - 1);
// expand radius if total width is larger than the circumference.
radius = Mathf.Max(radius, (totalWidth + margin) / (2 * Mathf.PI));
// total angle of monitors
var totalAngle = totalWidth / radius;
// layout
float angle = -totalAngle / 2;
var offsetRot = Quaternion.Euler(offsetAngle);
foreach (var info in monitors) {
@@ -53,7 +82,12 @@ public class MultipleMonitorRoundLayouter : MultipleMonitorLayouter
protected override void Update()
{
base.Update();
if (debugDraw) DebugDraw();
}
void DebugDraw()
{
// draw the circumference in the scene view.
var scale = transform.localScale.x;
var center = transform.position - Vector3.forward * radius * scale;
for (int i = 0; i < 100; ++i) {

View File

@@ -0,0 +1,23 @@
using UnityEngine;
using System.Collections;
public class RaycastTest : MonoBehaviour
{
public Transform from;
public Transform to;
void Update()
{
if (!from || !to) return;
Debug.DrawLine(from.position, to.position, Color.red);
foreach (var uddTexture in GameObject.FindObjectsOfType<uDesktopDuplication.Texture>()) {
var result = uddTexture.RayCast(from.position, to.position - from.position);
if (result.hit) {
Debug.DrawLine(result.position, result.position + result.normal, Color.yellow);
Debug.Log("COORD: " + result.coords + ", DESKTOP: " + result.desktopCoord);
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 810a4ad59c7d8d34e9b6014e8191fffe
timeCreated: 1481722966
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -6,10 +6,12 @@ public class ToggleMonitors : MonoBehaviour
{
if (Input.GetKeyDown(KeyCode.Tab)) {
var texture = GetComponent<uDesktopDuplication.Texture>();
var id = texture.monitorId;
var n = uDesktopDuplication.Manager.monitorCount;
if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)) {
texture.monitorId--;
texture.monitorId = (id - 1 < 0) ? 0 : (id - 1);
} else {
texture.monitorId++;
texture.monitorId = (id + 1 >= n) ? (n - 1) : (id + 1);
}
}
}

View File

@@ -47,7 +47,7 @@ public class UddSceneManager : MonoBehaviour
void Prev()
{
sceneNo = (sceneNo - 1) % scenes.Length;
sceneNo = (sceneNo + scenes.Length - 1) % scenes.Length;
Load();
}

View File

@@ -0,0 +1,49 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_Name: uDD_Screen_Unlit_Displacement
m_Shader: {fileID: 4800000, guid: 05df46eb51b13c84eabbdf4c53cc8db7, type: 3}
m_ShaderKeywords: BEND_ON _CULL_OFF _FORWARD_Z
m_LightmapFlags: 5
m_EnableInstancingVariants: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _CursorTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DispTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _Bend: 1
- _Cull: 0
- _DispFactor: 0.1
- _Displacement: 0.3
- _Forward: 1
- _InsideTessFactor: 1
- _Radius: 15.4
- _TessDistFactor: 3
- _TessDistPower: 1.545
- _TessEdgeLen: 1
- _TessFactor: 25
- _TessMaxDist: 10
- _TessMinDist: 0.5
- _Thickness: 1
- _Width: 1.92
m_Colors:
- _Color: {r: 1, g: 1, b: 1, a: 1}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 596fd740aeeee0d4cb4f962d4072954e
timeCreated: 1480074277
licenseType: Pro
NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -39,11 +39,11 @@ ModelImporter:
globalScale: 0.1
meshCompression: 0
addColliders: 0
importBlendShapes: 1
importBlendShapes: 0
swapUVChannels: 0
generateSecondaryUV: 0
useFileUnits: 1
optimizeMeshForGPU: 1
optimizeMeshForGPU: 0
keepQuads: 0
weldVertices: 1
secondaryUVAngleDistortion: 8

Binary file not shown.

View File

@@ -0,0 +1,87 @@
fileFormatVersion: 2
guid: f30f6cfd6aa37554ca886424cada7cbb
timeCreated: 1480072865
licenseType: Pro
ModelImporter:
serializedVersion: 19
fileIDToRecycleName:
100000: //RootNode
100002: uDD_Plane_MeshPart0
100004: uDD_Plane_MeshPart1
400000: //RootNode
400002: uDD_Plane_MeshPart0
400004: uDD_Plane_MeshPart1
2300000: //RootNode
2300002: uDD_Plane_MeshPart0
2300004: uDD_Plane_MeshPart1
3300000: //RootNode
3300002: uDD_Plane_MeshPart0
3300004: uDD_Plane_MeshPart1
4300000: uDD_Plane
4300002: uDD_Plane_MeshPart0
4300004: uDD_Plane_MeshPart1
9500000: //RootNode
materials:
importMaterials: 0
materialName: 0
materialSearch: 1
animations:
legacyGenerateAnimations: 4
bakeSimulation: 0
resampleCurves: 1
optimizeGameObjects: 0
motionNodeName:
animationImportErrors:
animationImportWarnings:
animationRetargetingWarnings:
animationDoRetargetingWarnings: 0
animationCompression: 1
animationRotationError: 0.5
animationPositionError: 0.5
animationScaleError: 0.5
animationWrapMode: 0
extraExposedTransformPaths: []
clipAnimations: []
isReadable: 0
meshes:
lODScreenPercentages: []
globalScale: 0.1
meshCompression: 0
addColliders: 0
importBlendShapes: 0
swapUVChannels: 0
generateSecondaryUV: 0
useFileUnits: 1
optimizeMeshForGPU: 1
keepQuads: 0
weldVertices: 1
secondaryUVAngleDistortion: 8
secondaryUVAreaDistortion: 15.000001
secondaryUVHardAngle: 88
secondaryUVPackMargin: 4
useFileScale: 1
tangentSpace:
normalSmoothAngle: 60
normalImportMode: 0
tangentImportMode: 2
importAnimation: 0
copyAvatar: 0
humanDescription:
human: []
skeleton: []
armTwist: 0.5
foreArmTwist: 0.5
upperLegTwist: 0.5
legTwist: 0.5
armStretch: 0.05
legStretch: 0.05
feetSpacing: 0
rootMotionBoneName:
hasTranslationDoF: 0
lastHumanDescriptionAvatarSource: {instanceID: 0}
animationType: 0
humanoidOversampling: 1
additionalBone: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: a3ded3542f0e6b74ea0ff9ea58aea2f2
folderAsset: yes
timeCreated: 1480693928
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,150 @@
fileFormatVersion: 2
guid: d3ab0ac3a3d6bb643af0a464a93be957
timeCreated: 1503496900
licenseType: Pro
PluginImporter:
serializedVersion: 2
iconMap: {}
executionOrder: {}
isPreloaded: 0
isOverridable: 0
platformData:
data:
first:
'': Any
second:
enabled: 0
settings:
Exclude Android: 0
Exclude Editor: 0
Exclude Linux: 0
Exclude Linux64: 0
Exclude LinuxUniversal: 0
Exclude OSXIntel: 0
Exclude OSXIntel64: 0
Exclude OSXUniversal: 0
Exclude Win: 0
Exclude Win64: 1
data:
first:
'': data
second:
enabled: 0
settings: {}
data:
first:
Android: Android
second:
enabled: 1
settings:
CPU: ARMv7
data:
first:
Any:
second:
enabled: 1
settings:
Exclude Editor: 0
Exclude Linux: 0
Exclude Linux64: 0
Exclude LinuxUniversal: 0
Exclude OSXIntel: 0
Exclude OSXIntel64: 0
Exclude OSXUniversal: 0
Exclude WebGL: 0
Exclude Win: 0
Exclude Win64: 1
data:
first:
Editor: Editor
second:
enabled: 1
settings:
CPU: x86
DefaultValueInitialized: true
OS: AnyOS
data:
first:
Facebook: WebGL
second:
enabled: 1
settings: {}
data:
first:
Facebook: Win
second:
enabled: 1
settings:
CPU: AnyCPU
data:
first:
Facebook: Win64
second:
enabled: 0
settings:
CPU: None
data:
first:
Standalone: Linux
second:
enabled: 1
settings:
CPU: x86
data:
first:
Standalone: Linux64
second:
enabled: 1
settings:
CPU: None
data:
first:
Standalone: LinuxUniversal
second:
enabled: 1
settings:
CPU: AnyCPU
data:
first:
Standalone: OSXIntel
second:
enabled: 1
settings:
CPU: AnyCPU
data:
first:
Standalone: OSXIntel64
second:
enabled: 1
settings:
CPU: None
data:
first:
Standalone: OSXUniversal
second:
enabled: 1
settings:
CPU: AnyCPU
data:
first:
Standalone: Win
second:
enabled: 1
settings:
CPU: AnyCPU
data:
first:
Standalone: Win64
second:
enabled: 0
settings:
CPU: None
data:
first:
WebGL: WebGL
second:
enabled: 1
settings: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,20 +1,150 @@
fileFormatVersion: 2
guid: 02fc121822cf2ea4e82e16c4a28bf711
timeCreated: 1477546714
guid: 7cb91c9ae744dc5429005b20e11f4f37
timeCreated: 1503505907
licenseType: Pro
PluginImporter:
serializedVersion: 1
serializedVersion: 2
iconMap: {}
executionOrder: {}
isPreloaded: 0
isOverridable: 0
platformData:
Any:
enabled: 1
settings: {}
Editor:
enabled: 0
settings:
DefaultValueInitialized: true
data:
first:
'': Any
second:
enabled: 0
settings:
Exclude Android: 0
Exclude Editor: 0
Exclude Linux: 0
Exclude Linux64: 0
Exclude LinuxUniversal: 0
Exclude OSXIntel: 0
Exclude OSXIntel64: 0
Exclude OSXUniversal: 0
Exclude Win: 1
Exclude Win64: 0
data:
first:
'': data
second:
enabled: 0
settings: {}
data:
first:
Android: Android
second:
enabled: 1
settings:
CPU: ARMv7
data:
first:
Any:
second:
enabled: 1
settings:
Exclude Editor: 0
Exclude Linux: 0
Exclude Linux64: 0
Exclude LinuxUniversal: 0
Exclude OSXIntel: 0
Exclude OSXIntel64: 0
Exclude OSXUniversal: 0
Exclude WebGL: 0
Exclude Win: 1
Exclude Win64: 0
data:
first:
Editor: Editor
second:
enabled: 1
settings:
CPU: x86_64
DefaultValueInitialized: true
OS: AnyOS
data:
first:
Facebook: WebGL
second:
enabled: 1
settings: {}
data:
first:
Facebook: Win
second:
enabled: 0
settings:
CPU: None
data:
first:
Facebook: Win64
second:
enabled: 1
settings:
CPU: AnyCPU
data:
first:
Standalone: Linux
second:
enabled: 1
settings:
CPU: None
data:
first:
Standalone: Linux64
second:
enabled: 1
settings:
CPU: x86_64
data:
first:
Standalone: LinuxUniversal
second:
enabled: 1
settings:
CPU: AnyCPU
data:
first:
Standalone: OSXIntel
second:
enabled: 1
settings:
CPU: None
data:
first:
Standalone: OSXIntel64
second:
enabled: 1
settings:
CPU: AnyCPU
data:
first:
Standalone: OSXUniversal
second:
enabled: 1
settings:
CPU: AnyCPU
data:
first:
Standalone: Win
second:
enabled: 0
settings:
CPU: None
data:
first:
Standalone: Win64
second:
enabled: 1
settings:
CPU: AnyCPU
data:
first:
WebGL: WebGL
second:
enabled: 1
settings: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,71 +0,0 @@
using UnityEngine;
using UnityEngine.Assertions;
using System.Collections.Generic;
namespace uDesktopDuplication
{
[AddComponentMenu("uDesktopDuplication/Cursor"), RequireComponent(typeof(Texture))]
public class Cursor : MonoBehaviour
{
[SerializeField] Vector2 modelScale = Vector2.one;
Vector3 worldPosition { get; set; }
private Texture uddTexture_;
private Monitor monitor { get { return uddTexture_.monitor; } }
private Dictionary<int, Texture2D> textures_ = new Dictionary<int, Texture2D>();
void Start()
{
uddTexture_ = GetComponent<Texture>();
}
void Update()
{
if (monitor.isCursorVisible) {
UpdatePosition();
UpdateTexture();
}
UpdateMaterial();
}
void UpdatePosition()
{
var x = (1f * monitor.cursorX / monitor.width - 0.5f) * modelScale.x;
var y = (1f * monitor.cursorY / monitor.height - 0.5f) * modelScale.y;
var iy = uddTexture_.invertY ? -1 : +1;
var localPos = transform.right * x + iy * transform.up * y;
worldPosition = transform.TransformPoint(localPos);
}
void UpdateTexture()
{
var w = monitor.cursorShapeWidth;
var h = monitor.cursorShapeHeight;
if (w == 0 || h == 0) return;
var key = w + h * 100;
if (!textures_.ContainsKey(key)) {
var texture = new Texture2D(w, h, TextureFormat.BGRA32, false);
texture.wrapMode = TextureWrapMode.Clamp;
textures_.Add(key, texture);
}
var cursorTexture = textures_[key];
Assert.IsNotNull(cursorTexture);
monitor.GetCursorTexture(cursorTexture.GetNativeTexturePtr());
uddTexture_.material.SetTexture("_CursorTex", cursorTexture);
}
void UpdateMaterial()
{
var x = monitor.isCursorVisible ? (float)monitor.cursorX / monitor.width : -9999f;
var y = monitor.isCursorVisible ? (float)monitor.cursorY / monitor.height : -9999f;
var w = (float)monitor.cursorShapeWidth / monitor.width;
var h = (float)monitor.cursorShapeHeight / monitor.height;
uddTexture_.material.SetVector("_CursorPositionScale", new Vector4(x, y, w, h));
}
}
}

View File

@@ -1,7 +1,10 @@
using System;
using UnityEngine;
using System;
using System.Text;
using System.Runtime.InteropServices;
#pragma warning disable 114, 465
namespace uDesktopDuplication
{
@@ -14,6 +17,7 @@ public enum Message
public enum CursorShapeType
{
Unspecified = 0,
MonoChrome = 1,
Color = 2,
MaskedColor = 4,
@@ -28,17 +32,18 @@ public enum MonitorRotation
Rotate270 = 4
}
public enum MonitorState
public enum DuplicatorState
{
NotSet = -1,
Available = 0,
InvalidArg = 1,
AccessDenied = 2,
Unsupported = 3,
CurrentlyNotAvailable = 4,
SessionDisconnected = 5,
AccessLost = 6,
TextureSizeInconsistent = 7,
Ready = 0,
Running = 1,
InvalidArg = 2,
AccessDenied = 3,
Unsupported = 4,
CurrentlyNotAvailable = 5,
SessionDisconnected = 6,
AccessLost = 7,
TextureSizeInconsistent = 8,
Unknown = 999,
}
@@ -49,6 +54,26 @@ public enum DebugMode
UnityLog = 2, /* currently has bug when app exits. */
}
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
[MarshalAs(UnmanagedType.I4)]
public int left;
[MarshalAs(UnmanagedType.I4)]
public int top;
[MarshalAs(UnmanagedType.I4)]
public int right;
[MarshalAs(UnmanagedType.I4)]
public int bottom;
}
[StructLayout(LayoutKind.Sequential)]
public struct DXGI_OUTDUPL_MOVE_RECT
{
public RECT source;
public RECT destination;
}
public static class Lib
{
public delegate void MessageHandler(Message message);
@@ -56,9 +81,11 @@ public static class Lib
public delegate void DebugLogDelegate(string str);
[DllImport("uDesktopDuplication")]
public static extern void InitializeUDD();
public static extern bool IsInitialized();
[DllImport("uDesktopDuplication")]
public static extern void FinalizeUDD();
public static extern void Initialize();
[DllImport("uDesktopDuplication")]
public static extern void Finalize();
[DllImport("uDesktopDuplication")]
public static extern void Reinitialize();
[DllImport("uDesktopDuplication")]
@@ -72,9 +99,9 @@ public static class Lib
[DllImport("uDesktopDuplication")]
public static extern void SetDebugMode(DebugMode mode);
[DllImport("uDesktopDuplication")]
public static extern void SetLogFunc(IntPtr func);
public static extern void SetLogFunc(DebugLogDelegate func);
[DllImport("uDesktopDuplication")]
public static extern void SetErrorFunc(IntPtr func);
public static extern void SetErrorFunc(DebugLogDelegate func);
[DllImport("uDesktopDuplication")]
public static extern int GetMonitorCount();
[DllImport("uDesktopDuplication")]
@@ -86,13 +113,11 @@ public static class Lib
[DllImport("uDesktopDuplication")]
public static extern int GetTotalHeight();
[DllImport("uDesktopDuplication")]
public static extern void SetTimeout(int timeout);
[DllImport("uDesktopDuplication")]
public static extern IntPtr GetRenderEventFunc();
[DllImport("uDesktopDuplication")]
public static extern int GetId(int id);
[DllImport("uDesktopDuplication")]
public static extern MonitorState GetState(int id);
public static extern DuplicatorState GetState(int id);
[DllImport("uDesktopDuplication")]
public static extern void GetName(int id, StringBuilder buf, int len);
[DllImport("uDesktopDuplication")]
@@ -118,21 +143,37 @@ public static class Lib
[DllImport("uDesktopDuplication")]
public static extern bool IsCursorVisible(int id);
[DllImport("uDesktopDuplication")]
public static extern int GetCursorX(int id);
public static extern int GetCursorX();
[DllImport("uDesktopDuplication")]
public static extern int GetCursorY(int id);
public static extern int GetCursorY();
[DllImport("uDesktopDuplication")]
public static extern int GetCursorShapeWidth(int id);
public static extern int GetCursorShapeWidth();
[DllImport("uDesktopDuplication")]
public static extern int GetCursorShapeHeight(int id);
public static extern int GetCursorShapeHeight();
[DllImport("uDesktopDuplication")]
public static extern int GetCursorShapePitch(int id);
public static extern int GetCursorShapePitch();
[DllImport("uDesktopDuplication")]
public static extern CursorShapeType GetCursorShapeType(int id);
public static extern CursorShapeType GetCursorShapeType();
[DllImport("uDesktopDuplication")]
public static extern void GetCursorTexture(int id, System.IntPtr ptr);
[DllImport("uDesktopDuplication")]
public static extern int SetTexturePtr(int id, IntPtr ptr);
[DllImport("uDesktopDuplication")]
public static extern int GetMoveRectCount(int id);
[DllImport("uDesktopDuplication", EntryPoint = "GetMoveRects")]
private static extern IntPtr GetMoveRects_Internal(int id);
[DllImport("uDesktopDuplication")]
public static extern int GetDirtyRectCount(int id);
[DllImport("uDesktopDuplication", EntryPoint = "GetDirtyRects")]
private static extern IntPtr GetDirtyRects_Internal(int id);
[DllImport("uDesktopDuplication", EntryPoint = "GetPixels")]
private static extern bool GetPixels_Internal(int id, System.IntPtr ptr, int x, int y, int width, int height);
[DllImport("uDesktopDuplication")]
public static extern bool HasBeenUpdated(int id);
[DllImport("uDesktopDuplication")]
public static extern bool UseGetPixels(int id, bool use);
[DllImport("uDesktopDuplication")]
public static extern void SetFrameRate(uint frameRate);
public static string GetName(int id)
{
@@ -140,6 +181,60 @@ public static class Lib
GetName(id, buf, buf.Capacity);
return buf.ToString();
}
public static DXGI_OUTDUPL_MOVE_RECT[] GetMoveRects(int id)
{
var count = GetMoveRectCount(id);
var rects = new DXGI_OUTDUPL_MOVE_RECT[count];
var ptr = GetMoveRects_Internal(id);
var size = Marshal.SizeOf(typeof(DXGI_OUTDUPL_MOVE_RECT));
for (int i = 0; i < count; ++i) {
var data = new IntPtr(ptr.ToInt64() + size * i);
rects[i] = (DXGI_OUTDUPL_MOVE_RECT)Marshal.PtrToStructure(data, typeof(DXGI_OUTDUPL_MOVE_RECT));
}
return rects;
}
public static RECT[] GetDirtyRects(int id)
{
var count = GetDirtyRectCount(id);
var rects = new RECT[count];
var ptr = GetDirtyRects_Internal(id);
var size = Marshal.SizeOf(typeof(RECT));
for (int i = 0; i < count; ++i) {
var data = new IntPtr(ptr.ToInt64() + size * i);
rects[i] = (RECT)Marshal.PtrToStructure(data, typeof(RECT));
}
return rects;
}
public static Color32[] GetPixels(int id, int x, int y, int width, int height)
{
var color = new Color32[width * height];
GetPixels(id, color, x, y, width, height);
return color;
}
public static bool GetPixels(int id, Color32[] colors, int x, int y, int width, int height)
{
if (colors.Length < width * height) {
Debug.LogErrorFormat("colors is small.", id, x, y, width, height);
return false;
}
var handle = GCHandle.Alloc(colors, GCHandleType.Pinned);
var ptr = handle.AddrOfPinnedObject();
if (!GetPixels_Internal(id, ptr, x, y, width, height)) {
Debug.LogErrorFormat("GetPixels({0}, {1}, {2}, {3}, {4}) failed.", id, x, y, width, height);
return false;
}
handle.Free();
return true;
}
public static Color32 GetPixel(int id, int x, int y)
{
return GetPixels(id, x, y, 1, 1)[0];
}
}
}

View File

@@ -15,15 +15,17 @@ public class Manager : MonoBehaviour
public static Manager CreateInstance()
{
if (instance_) {
return instance_;
}
if (instance_ != null) return instance_;
var manager = FindObjectOfType<Manager>();
if (manager) return manager;
if (manager) {
instance_ = manager;
return manager;
}
var go = new GameObject("uDesktopDuplicationManager");
return go.AddComponent<Manager>();
instance_ = go.AddComponent<Manager>();
return instance_;
}
private List<Monitor> monitors_ = new List<Monitor>();
@@ -50,13 +52,23 @@ public class Manager : MonoBehaviour
}
}
[Tooltip("Debug mode is not applied while running.")]
[SerializeField] DebugMode debugMode = DebugMode.File;
[SerializeField] int desktopDuplicationApiTimeout = 0;
[SerializeField] float retryReinitializationDuration = 1f;
private Coroutine renderCoroutine_ = null;
private bool shouldReinitialize_ = false;
private float reinitializationTimer_ = 0f;
private bool isFirstFrame_ = true;
public static event Lib.DebugLogDelegate onDebugLog = OnDebugLog;
public static event Lib.DebugLogDelegate onDebugErr = OnDebugErr;
[AOT.MonoPInvokeCallback(typeof(Lib.DebugLogDelegate))]
private static void OnDebugLog(string msg) { Debug.Log(msg); }
[AOT.MonoPInvokeCallback(typeof(Lib.DebugLogDelegate))]
private static void OnDebugErr(string msg) { Debug.LogError(msg); }
public delegate void ReinitializeHandler();
public static event ReinitializeHandler onReinitialized;
@@ -72,28 +84,49 @@ public class Manager : MonoBehaviour
void Awake()
{
Lib.SetDebugMode(debugMode);
Lib.InitializeUDD();
Lib.SetTimeout(desktopDuplicationApiTimeout);
// for simple singleton
if (instance_ != null) {
if (instance_ == this) {
return;
}
if (instance_ != null && instance_ != this) {
Destroy(gameObject);
return;
}
instance_ = this;
Lib.SetDebugMode(debugMode);
Lib.SetLogFunc(onDebugLog);
Lib.SetErrorFunc(onDebugErr);
Lib.Initialize();
CreateMonitors();
#if UNITY_2018_1_OR_NEWER
Shader.DisableKeyword("USE_GAMMA_TO_LINEAR_SPACE");
#else
Shader.EnableKeyword("USE_GAMMA_TO_LINEAR_SPACE");
#endif
}
void OnApplicationQuit()
{
Lib.FinalizeUDD();
Lib.Finalize();
DestroyMonitors();
}
void OnEnable()
{
renderCoroutine_ = StartCoroutine(OnRender());
if (!isFirstFrame_) {
Reinitialize();
}
Lib.SetDebugMode(debugMode);
Lib.SetLogFunc(onDebugLog);
}
void OnDisable()
@@ -102,6 +135,9 @@ public class Manager : MonoBehaviour
StopCoroutine(renderCoroutine_);
renderCoroutine_ = null;
}
Lib.SetLogFunc(null);
Lib.SetErrorFunc(null);
}
void Update()
@@ -109,6 +145,7 @@ public class Manager : MonoBehaviour
Lib.Update();
ReinitializeIfNeeded();
UpdateMessage();
isFirstFrame_ = false;
}
[ContextMenu("Reinitialize")]
@@ -128,11 +165,13 @@ public class Manager : MonoBehaviour
for (int i = 0; i < monitors.Count; ++i) {
var monitor = monitors[i];
var state = monitor.state;
if (
monitor.state == MonitorState.NotSet ||
monitor.state == MonitorState.AccessLost ||
monitor.state == MonitorState.AccessDenied ||
monitor.state == MonitorState.SessionDisconnected
state == DuplicatorState.NotSet ||
state == DuplicatorState.AccessLost ||
state == DuplicatorState.AccessDenied ||
state == DuplicatorState.SessionDisconnected ||
state == DuplicatorState.Unknown
) {
reinitializeNeeded = true;
break;

View File

@@ -11,21 +11,23 @@ public class Monitor
switch (state)
{
case MonitorState.Available:
case DuplicatorState.Ready:
break;
case MonitorState.InvalidArg:
case DuplicatorState.Running:
break;
case DuplicatorState.InvalidArg:
Debug.LogErrorFormat("[uDD] {0}:{1} => Invalid.", id, name);
break;
case MonitorState.AccessDenied:
case DuplicatorState.AccessDenied:
Debug.LogWarningFormat("[uDD] {0}:{1} => Access Denied.", id, name);
break;
case MonitorState.Unsupported:
case DuplicatorState.Unsupported:
Debug.LogWarningFormat("[uDD] {0}:{1} => Unsupported.", id, name);
break;
case MonitorState.SessionDisconnected:
case DuplicatorState.SessionDisconnected:
Debug.LogWarningFormat("[uDD] {0}:{1} => Disconnected.", id, name);
break;
case MonitorState.NotSet:
case DuplicatorState.NotSet:
Debug.LogErrorFormat("[uDD] {0}:{1} => Something wrong.", id, name);
break;
default:
@@ -40,7 +42,6 @@ public class Monitor
~Monitor()
{
DestroyTexture();
}
public int id
@@ -54,14 +55,19 @@ public class Monitor
get { return id < Manager.monitorCount; }
}
public MonitorState state
public DuplicatorState state
{
get { return Lib.GetState(id); }
}
public bool available
{
get { return state == MonitorState.Available; }
get
{
return
state == DuplicatorState.Ready ||
state == DuplicatorState.Running;
}
}
public string name
@@ -146,12 +152,22 @@ public class Monitor
public bool isHorizontal
{
get { return width > height; }
get
{
return
(rotation == MonitorRotation.Identity) ||
(rotation == MonitorRotation.Rotate180);
}
}
public bool isVertical
{
get { return height > width; }
get
{
return
(rotation == MonitorRotation.Rotate90) ||
(rotation == MonitorRotation.Rotate270);
}
}
public bool isCursorVisible
@@ -161,12 +177,12 @@ public class Monitor
public int cursorX
{
get { return Lib.GetCursorX(id); }
get { return Lib.GetCursorMonitorId() == id ? Lib.GetCursorX() : -1; }
}
public int cursorY
{
get { return Lib.GetCursorY(id); }
get { return Lib.GetCursorMonitorId() == id ? Lib.GetCursorY() : -1; }
}
public int systemCursorX
@@ -189,17 +205,56 @@ public class Monitor
public int cursorShapeWidth
{
get { return Lib.GetCursorShapeWidth(id); }
get { return Lib.GetCursorShapeWidth(); }
}
public int cursorShapeHeight
{
get { return Lib.GetCursorShapeHeight(id); }
get { return Lib.GetCursorShapeHeight(); }
}
public CursorShapeType cursorShapeType
{
get { return Lib.GetCursorShapeType(id); }
get { return Lib.GetCursorShapeType(); }
}
public int moveRectCount
{
get { return Lib.GetMoveRectCount(id); }
}
public DXGI_OUTDUPL_MOVE_RECT[] moveRects
{
get { return Lib.GetMoveRects(id); }
}
public int dirtyRectCount
{
get { return Lib.GetDirtyRectCount(id); }
}
public RECT[] dirtyRects
{
get { return Lib.GetDirtyRects(id); }
}
public bool hasBeenUpdated
{
get { return Lib.HasBeenUpdated(id); }
}
bool useGetPixels_ = false;
public bool useGetPixels
{
get
{
return useGetPixels_;
}
set
{
useGetPixels_ = value;
Lib.UseGetPixels(id, value);
}
}
public bool shouldBeUpdated
@@ -220,6 +275,7 @@ public class Monitor
}
private Texture2D texture_;
private System.IntPtr texturePtr_;
public Texture2D texture
{
get
@@ -232,8 +288,8 @@ public class Monitor
public void Render()
{
if (texture_ && available) {
Lib.SetTexturePtr(id, texture_.GetNativeTexturePtr());
if (texture_ && available && texturePtr_ != System.IntPtr.Zero) {
Lib.SetTexturePtr(id, texturePtr_);
GL.IssuePluginEvent(Lib.GetRenderEventFunc(), id);
}
}
@@ -270,6 +326,7 @@ public class Monitor
var w = isHorizontal ? width : height;
var h = isHorizontal ? height : width;
texture_ = new Texture2D(w, h, TextureFormat.BGRA32, false);
texturePtr_ = texture_.GetNativeTexturePtr();
}
public void DestroyTexture()
@@ -277,6 +334,7 @@ public class Monitor
if (texture_) {
Object.Destroy(texture_);
texture_ = null;
texturePtr_ = System.IntPtr.Zero;
}
}
@@ -284,6 +342,33 @@ public class Monitor
{
CreateTextureIfNeeded();
}
public Color32[] GetPixels(int x, int y, int width, int height)
{
if (!useGetPixels_) {
Debug.LogErrorFormat("Please set Monitor[{0}].useGetPixels as true.", id);
return null;
}
return Lib.GetPixels(id, x, y, width, height);
}
public bool GetPixels(Color32[] colors, int x, int y, int width, int height)
{
if (!useGetPixels_) {
Debug.LogErrorFormat("Please set Monitor[{0}].useGetPixels as true.", id);
return false;
}
return Lib.GetPixels(id, colors, x, y, width, height);
}
public Color32 GetPixel(int x, int y)
{
if (!useGetPixels_) {
Debug.LogErrorFormat("Please set Monitor[{0}].useGetPixels as true.", id);
return Color.black;
}
return Lib.GetPixel(id, x, y);
}
}
}

View File

@@ -3,10 +3,10 @@
namespace uDesktopDuplication
{
[AddComponentMenu("uDesktopDuplication/Texture"), RequireComponent(typeof(Cursor))]
[AddComponentMenu("uDesktopDuplication/Texture")]
public class Texture : MonoBehaviour
{
private Monitor monitor_;
Monitor monitor_;
public Monitor monitor
{
get { return monitor_; }
@@ -14,32 +14,113 @@ public class Texture : MonoBehaviour
{
monitor_ = value;
if (monitor_ != null) {
material = GetComponent<Renderer>().material; // clone
material.mainTexture = monitor_.texture;
material.SetFloat("_Width", transform.localScale.x);
width = transform.localScale.x;
rotation = monitor.rotation;
invertX = invertX_;
invertY = invertY_;
useClip = useClip_;
}
}
}
int lastMonitorId_ = 0;
public int monitorId
{
get { return monitor.id; }
set { monitor = Manager.GetMonitor(value); }
}
[Header("Invert UVs")]
public bool invertX = false;
public bool invertY = false;
[SerializeField] bool invertX_ = false;
public bool invertX
{
get
{
return invertX_;
}
set
{
invertX_ = value;
if (invertX_) {
material.EnableKeyword("INVERT_X");
} else {
material.DisableKeyword("INVERT_X");
}
}
}
[Header("Clip")]
public bool useClip = false;
[SerializeField] bool invertY_ = false;
public bool invertY
{
get
{
return invertY_;
}
set
{
invertY_ = value;
if (invertY_) {
material.EnableKeyword("INVERT_Y");
} else {
material.DisableKeyword("INVERT_Y");
}
}
}
public MonitorRotation rotation
{
get
{
return monitor.rotation;
}
private set
{
switch (value)
{
case MonitorRotation.Identity:
material.DisableKeyword("ROTATE90");
material.DisableKeyword("ROTATE180");
material.DisableKeyword("ROTATE270");
break;
case MonitorRotation.Rotate90:
material.EnableKeyword("ROTATE90");
material.DisableKeyword("ROTATE180");
material.DisableKeyword("ROTATE270");
break;
case MonitorRotation.Rotate180:
material.DisableKeyword("ROTATE90");
material.EnableKeyword("ROTATE180");
material.DisableKeyword("ROTATE270");
break;
case MonitorRotation.Rotate270:
material.DisableKeyword("ROTATE90");
material.DisableKeyword("ROTATE180");
material.EnableKeyword("ROTATE270");
break;
default:
break;
}
}
}
[SerializeField] bool useClip_ = false;
public Vector2 clipPos = Vector2.zero;
public Vector2 clipScale = new Vector2(0.2f, 0.2f);
public enum MeshForwardDirection
public bool useClip
{
Y = 0,
Z = 1,
get
{
return useClip_;
}
set
{
useClip_ = value;
if (useClip_) {
material.EnableKeyword("USE_CLIP");
} else {
material.DisableKeyword("USE_CLIP");
}
}
}
public bool bend
@@ -52,12 +133,19 @@ public class Texture : MonoBehaviour
{
if (value) {
material.EnableKeyword("BEND_ON");
material.SetInt("_Bend", 1);
} else {
material.DisableKeyword("BEND_ON");
material.SetInt("_Bend", 0);
}
}
}
public enum MeshForwardDirection
{
Y = 0,
Z = 1,
}
public MeshForwardDirection meshForwardDirection
{
get
@@ -69,18 +157,36 @@ public class Texture : MonoBehaviour
switch (value) {
case MeshForwardDirection.Y:
material.SetInt("_Forward", 0);
material.EnableKeyword("_BEND_Y");
material.DisableKeyword("_BEND_Z");
material.EnableKeyword("_FORWARD_Y");
material.DisableKeyword("_FORWARD_Z");
break;
case MeshForwardDirection.Z:
material.SetInt("_Forward", 1);
material.DisableKeyword("_BEND_Y");
material.EnableKeyword("_BEND_Z");
material.DisableKeyword("_FORWARD_Y");
material.EnableKeyword("_FORWARD_Z");
break;
}
}
}
public enum Culling
{
Off = 0,
Front = 1,
Back = 2,
}
public Culling culling
{
get
{
return (Culling)material.GetInt("_Cull");
}
set
{
material.SetInt("_Cull", (int)value);
}
}
public float radius
{
get { return material.GetFloat("_Radius"); }
@@ -99,15 +205,39 @@ public class Texture : MonoBehaviour
set { material.SetFloat("_Thickness", value); }
}
Material material_;
public Material material
{
get;
private set;
get
{
if (Application.isPlaying) {
return material_ ?? (material_ = GetComponent<Renderer>().material); // clone
} else {
return GetComponent<Renderer>().sharedMaterial;
}
}
}
void Awake()
Mesh mesh
{
AddCursorIfNotAttached();
get
{
return GetComponent<MeshFilter>().sharedMesh;
}
}
public float worldWidth
{
get
{
return transform.localScale.x * (mesh.bounds.extents.x * 2f);
}
}
public float worldHeight
{
get
{
return transform.localScale.y * (mesh.bounds.extents.y * 2f);
}
}
void OnEnable()
@@ -125,83 +255,197 @@ public class Texture : MonoBehaviour
void Update()
{
monitor.shouldBeUpdated = true;
KeepMonitor();
RequireUpdate();
UpdateMaterial();
}
void AddCursorIfNotAttached()
void KeepMonitor()
{
if (!GetComponent<Cursor>())
if (monitor == null) {
Reinitialize();
} else {
lastMonitorId_ = monitorId;
}
}
void RequireUpdate()
{
if (monitor != null)
{
gameObject.AddComponent<Cursor>();
monitor.shouldBeUpdated = true;
}
}
void Reinitialize()
{
// Monitor instance is released here when initialized.
monitor = Manager.GetMonitor(monitor.id);
monitor = Manager.GetMonitor(lastMonitorId_);
}
int clipPositionScaleKey_ = Shader.PropertyToID("_ClipPositionScale");
void UpdateMaterial()
{
Invert();
Rotate();
Clip();
}
width = transform.localScale.x;
void Invert()
{
if (invertX) {
material.EnableKeyword("INVERT_X");
} else {
material.DisableKeyword("INVERT_X");
if (monitor != null) {
rotation = monitor.rotation;
}
if (invertY) {
material.EnableKeyword("INVERT_Y");
} else {
material.DisableKeyword("INVERT_Y");
}
material.SetVector(clipPositionScaleKey_, new Vector4(clipPos.x, clipPos.y, clipScale.x, clipScale.y));
}
void Rotate()
public Vector3 GetWorldPositionFromCoord(Vector2 coord)
{
switch (monitor.rotation)
{
case MonitorRotation.Identity:
material.DisableKeyword("ROTATE90");
material.DisableKeyword("ROTATE180");
material.DisableKeyword("ROTATE270");
break;
case MonitorRotation.Rotate90:
material.EnableKeyword("ROTATE90");
material.DisableKeyword("ROTATE180");
material.DisableKeyword("ROTATE270");
break;
case MonitorRotation.Rotate180:
material.DisableKeyword("ROTATE90");
material.EnableKeyword("ROTATE180");
material.DisableKeyword("ROTATE270");
break;
case MonitorRotation.Rotate270:
material.DisableKeyword("ROTATE90");
material.DisableKeyword("ROTATE180");
material.EnableKeyword("ROTATE270");
break;
default:
break;
}
return GetWorldPositionFromCoord((int)coord.x, (int)coord.y);
}
void Clip()
public Vector3 GetWorldPositionFromCoord(int u, int v)
{
// Local position (scale included).
var x = (float)(u - monitor.width / 2) / monitor.width;
var y = -(float)(v - monitor.height / 2) / monitor.height;
var localPos = new Vector3(worldWidth * x, worldHeight * y, 0f);
// Bending
if (bend) {
var angle = localPos.x / radius;
if (meshForwardDirection == MeshForwardDirection.Y) {
localPos.y -= radius * (1f - Mathf.Cos(angle));
} else {
localPos.z -= radius * (1f - Mathf.Cos(angle));
}
localPos.x = radius * Mathf.Sin(angle);
}
// To world position
return transform.position + (transform.rotation * localPos);
}
public struct RayCastResult
{
public bool hit;
public Texture texture;
public Vector3 position;
public Vector3 normal;
public Vector2 coords;
public Vector2 desktopCoord;
}
static readonly RayCastResult raycastFailedResult = new RayCastResult {
hit = false,
texture = null,
position = Vector3.zero,
normal = Vector3.forward,
coords = Vector2.zero,
desktopCoord = Vector2.zero,
};
// This function can be used only for vertical (= MeshForwardDirection.Z) plane.
public RayCastResult RayCast(Vector3 from, Vector3 dir)
{
var r = radius;
var center = transform.position - transform.forward * r;
// Localize the start point of the ray and the direction.
var trs = Matrix4x4.TRS(center, transform.rotation, Vector3.one);
var invTrs = trs.inverse;
Vector3 localFrom = invTrs.MultiplyPoint3x4(from);
Vector3 localDir = invTrs.MultiplyVector(dir).normalized;
// Calculate the intersection points of circle and line on the X-Z plane.
var a = localDir.z / localDir.x;
var b = localFrom.z - a * localFrom.x;
var aa = a * a;
var bb = b * b;
var ab = a * b;
var rr = r * r;
var s = aa * rr - bb + rr;
if (s < 0f) {
return raycastFailedResult;
}
s = Mathf.Sqrt(s);
var t = aa + 1;
var lx0 = (-s - ab) / t;
var lz0 = (b - a * s) / t;
var to0 = new Vector3(lx0, 0f, lz0);
var lx1 = (s - ab) / t;
var lz1 = (a * s + b) / t;
var to1 = new Vector3(lx1, 0f, lz1);
var to = (Vector3.Dot(localDir, to0) > 0f) ? to0 : to1;
// Check if the point is inner angle of mesh width.
var toAngle = Mathf.Atan2(to.x, to.z);
var halfWidthAngle = (worldWidth / radius) * 0.5f;
if (Mathf.Abs(toAngle) > halfWidthAngle) {
return raycastFailedResult;
}
// Calculate the intersection points on XZ-Y plane.
var v = to - localFrom;
var l = Mathf.Sqrt(Mathf.Pow(v.x, 2f) + Mathf.Pow(v.z, 2f));
var ly = localFrom.y + l * localDir.y / Mathf.Sqrt(Mathf.Pow(localDir.x, 2f) + Mathf.Pow(localDir.z, 2f));
// Check if the point is inner mesh height.
var halfHeight = worldHeight * 0.5f;
if (Mathf.Abs(ly) > halfHeight) {
return raycastFailedResult;
}
// Check hit position is in the range of the ray.
to.y = ly;
var hitPos = trs.MultiplyPoint(to);
if ((hitPos - from).magnitude > dir.magnitude) {
return raycastFailedResult;
}
// Calculate coordinates.
var coordX = toAngle / halfWidthAngle * 0.5f;
var coordY = ly / halfHeight * 0.5f;
// Zoom
if (useClip) {
material.EnableKeyword("USE_CLIP");
material.SetVector("_ClipPositionScale", new Vector4(clipPos.x, clipPos.y, clipScale.x, clipScale.y));
} else {
material.DisableKeyword("USE_CLIP");
coordX = clipPos.x + (0.5f + coordX) * clipScale.x;
coordX -= Mathf.Floor(coordX);
coordX -= 0.5f;
coordY = (1f - clipPos.y) + (coordY - 0.5f) * clipScale.y;
coordY -= Mathf.Floor(coordY);
coordY -= 0.5f;
}
// Desktop position
int desktopX = monitor.left + (int)((coordX + 0.5f) * monitor.width);
int desktopY = monitor.top + (int)((0.5f - coordY) * monitor.height);
// Calculate normal.
var normal = new Vector3(-to.x, 0f, -to.z);
// Result
return new RayCastResult {
hit = true,
texture = this,
position = trs.MultiplyPoint(to),
normal = trs.MultiplyVector(normal).normalized,
coords = new Vector2(coordX, coordY),
desktopCoord = new Vector2(desktopX, desktopY)
};
}
public static RayCastResult RayCastAll(Vector3 from, Vector3 dir)
{
foreach (var uddTexture in GameObject.FindObjectsOfType<uDesktopDuplication.Texture>()) {
var result = uddTexture.RayCast(from, dir);
if (result.hit) return result;
}
return raycastFailedResult;
}
}

View File

@@ -58,59 +58,74 @@ inline float2 uddClipUV(float2 uv)
inline void uddConvertToLinearIfNeeded(inout fixed3 rgb)
{
#ifdef USE_GAMMA_TO_LINEAR_SPACE
if (!IsGammaSpace()) {
rgb = GammaToLinearSpace(rgb);
}
#endif
}
inline fixed4 uddGetScreenTexture(float2 uv)
{
fixed4 c = tex2D(_MainTex, uv);
return c;
}
inline fixed4 uddGetCursorTexture(float2 uv)
{
uv.x = (uv.x - _CursorX) / _CursorWidth;
uv.y = (uv.y - _CursorY) / _CursorHeight;
fixed4 c = tex2D(_CursorTex, uv);
fixed a = step(0, uv.x) * step(0, uv.y) * step(uv.x, 1) * step(uv.y, 1);
c.a *= step(0.01, a);
return c;
}
inline fixed4 uddGetScreenTextureWithCursor(float2 uv)
inline fixed4 uddGetTexture(sampler2D tex, float2 uv)
{
uv = uddInvertUV(uv);
#ifdef USE_CLIP
uv = uddClipUV(uv);
#endif
fixed4 screen = uddGetScreenTexture(uddRotateUV(uv));
fixed4 cursor = uddGetCursorTexture(uv);
fixed4 color = lerp(screen, cursor, cursor.a);
uddConvertToLinearIfNeeded(color.rgb);
return color;
fixed4 c = tex2D(tex, uddRotateUV(uv));
uddConvertToLinearIfNeeded(c.rgb);
return c;
}
inline void uddBendVertex(inout float4 v, half radius, half width, half thickness)
inline fixed4 uddGetScreenTexture(float2 uv)
{
return uddGetTexture(_MainTex, uv);
}
inline void uddBendVertex(inout float3 v, half radius, half width, half thickness)
{
#ifdef BEND_ON
half angle = width * v.x / radius;
#ifdef _FORWARD_Z
v.y *= thickness;
radius -= v.y;
v.y += radius * (1 - cos(angle));
#elif _FORWARD_Y
v.z *= thickness;
radius -= v.z;
v.z += radius * (1 - cos(angle));
radius += v.z;
v.z -= radius * (1 - cos(angle));
#elif _FORWARD_Y
v.y *= thickness;
radius += v.y;
v.y += radius * (1 - cos(angle));
#endif
v.x = radius * sin(angle) / width;
#else
#ifdef _FORWARD_Z
v.y *= thickness;
#elif _FORWARD_Y
v.z *= thickness;
#elif _FORWARD_Y
v.y *= thickness;
#endif
#endif
}
inline float3 uddRotateY(float3 n, float angle)
{
float c = cos(angle);
float s = sin(angle);
return float3(c * n.x - s * n.z, n.y, s * n.x + c * n.z);
}
inline float3 uddRotateX(float3 n, float angle)
{
float c = cos(angle);
float s = sin(angle);
return float3(n.x, c * n.y + s * n.z, -s * n.y + c * n.z);
}
inline void uddBendNormal(float4 x, inout float3 n, half radius, half width)
{
#ifdef BEND_ON
half angle = width * x / radius;
#ifdef _FORWARD_Z
n = uddRotateY(n, -angle);
#elif _FORWARD_Y
n = uddRotateX(n, -angle);
#endif
#endif
}

View File

@@ -7,6 +7,11 @@ Properties
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0, 1)) = 0.5
_Metallic ("Metallic", Range(0, 1)) = 0.0
[KeywordEnum(Y, Z)] _Forward("Mesh Forward Direction", Int) = 0
[Toggle(BEND_ON)] _Bend("Use Bend", Int) = 0
[PowerSlider(10.0)] _Radius("Bend Radius", Range(1, 100)) = 30
[PowerSlider(10.0)] _Thickness("Thickness", Range(0.01, 10)) = 1
_Width("Width", Range(0.0, 10.0)) = 1.0
[KeywordEnum(Off, Front, Back)] _Cull("Culling", Int) = 2
}
@@ -19,22 +24,33 @@ SubShader
CGPROGRAM
#pragma target 3.0
#pragma surface surf Standard fullforwardshadows
#pragma surface surf Standard fullforwardshadows vertex:vert
#pragma multi_compile ___ INVERT_X
#pragma multi_compile ___ INVERT_Y
#pragma multi_compile ___ ROTATE90 ROTATE180 ROTATE270
#pragma multi_compile ___ USE_BEND
#pragma multi_compile ___ USE_CLIP
#pragma multi_compile ___ BEND_ON
#pragma multi_compile _FORWARD_Y _FORWARD_Z
#pragma multi_compile ___ USE_GAMMA_TO_LINEAR_SPACE
#define SURFACE_SHADER
#include "./uDD_Common.cginc"
half _Glossiness;
half _Metallic;
half _Radius;
half _Width;
half _Thickness;
void vert(inout appdata_full v)
{
uddBendNormal(v.vertex.x, v.normal, _Radius, _Width);
uddBendVertex(v.vertex.xyz, _Radius, _Width, _Thickness);
}
void surf(Input IN, inout SurfaceOutputStandard o)
{
fixed4 c = uddGetScreenTextureWithCursor(IN.uv_MainTex) * _Color;
fixed4 c = uddGetScreenTexture(IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;

View File

@@ -5,11 +5,11 @@ Properties
{
_Color ("Color", Color) = (1, 1, 1, 1)
_MainTex ("Texture", 2D) = "white" {}
_CursorTex ("Cursor Texture", 2D) = "white" {}
[KeywordEnum(Y, Z)] _Forward("Mesh Forward Direction", Int) = 0
[Toggle(BEND_ON)] _Bend("Use Bend", Int) = 0
[PowerSlider(10.0)] _Radius("Bend Radius", Range(1, 100)) = 30
[PowerSlider(10.0)] _Thickness("Thickness", Range(0.01, 10)) = 1
_Width("Width", Range(0.0, 10.0)) = 1.0
[KeywordEnum(Off, Front, Back)] _Cull("Culling", Int) = 2
}
@@ -31,7 +31,7 @@ half _Thickness;
v2f vert(appdata v)
{
v2f o;
uddBendVertex(v.vertex, _Radius, _Width, _Thickness);
uddBendVertex(v.vertex.xyz, _Radius, _Width, _Thickness);
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
@@ -39,7 +39,7 @@ v2f vert(appdata v)
fixed4 frag(v2f i) : SV_Target
{
return uddGetScreenTextureWithCursor(i.uv);
return uddGetScreenTexture(i.uv);
}
ENDCG
@@ -55,6 +55,7 @@ Pass
#pragma multi_compile ___ USE_CLIP
#pragma multi_compile ___ BEND_ON
#pragma multi_compile _FORWARD_Y _FORWARD_Z
#pragma multi_compile ___ USE_GAMMA_TO_LINEAR_SPACE
ENDCG
}

View File

@@ -6,11 +6,11 @@ Properties
_Color ("Color", Color) = (1, 1, 1, 1)
_MainTex ("Texture", 2D) = "white" {}
_Mask ("Mask", Range(0, 1)) = 0.1
_CursorTex ("Cursor Texture", 2D) = "white" {}
[KeywordEnum(Y, Z)] _Forward("Mesh Forward Direction", Int) = 0
[Toggle(BEND_ON)] _Bend("Use Bend", Int) = 0
[PowerSlider(10.0)] _Radius("Bend Radius", Range(1, 100)) = 30
[PowerSlider(10.0)] _Thickness("Thickness", Range(0.01, 10)) = 1
_Width("Width", Range(0.0, 10.0)) = 1.0
[KeywordEnum(Off, Front, Back)] _Cull("Culling", Int) = 2
}
@@ -35,7 +35,7 @@ half _Thickness;
v2f vert(appdata v)
{
v2f o;
uddBendVertex(v.vertex, _Radius, _Width, _Thickness);
uddBendVertex(v.vertex.xyz, _Radius, _Width, _Thickness);
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
@@ -43,7 +43,7 @@ v2f vert(appdata v)
fixed4 frag(v2f i) : SV_Target
{
fixed4 tex = uddGetScreenTextureWithCursor(i.uv);
fixed4 tex = uddGetScreenTexture(i.uv);
fixed alpha = pow((tex.r + tex.g + tex.b) / 3.0, _Mask);
return fixed4(tex.rgb * _Color.rgb, alpha * _Color.a);
}
@@ -58,9 +58,10 @@ Pass
#pragma multi_compile ___ INVERT_X
#pragma multi_compile ___ INVERT_Y
#pragma multi_compile ___ ROTATE90 ROTATE180 ROTATE270
#pragma multi_compile ___ USE_BEND
#pragma multi_compile ___ USE_CLIP
#pragma multi_compile _BEND_OFF _BEND_Y _BEND_Z
#pragma multi_compile ___ BEND_ON
#pragma multi_compile _FORWARD_Y _FORWARD_Z
#pragma multi_compile ___ USE_GAMMA_TO_LINEAR_SPACE
ENDCG
}

View File

@@ -0,0 +1,179 @@
Shader "uDesktopDuplication/Unlit_Displacement"
{
Properties
{
_Color ("Color", Color) = (1, 1, 1, 1)
_MainTex ("Texture", 2D) = "white" {}
[KeywordEnum(Y, Z)] _Forward("Mesh Forward Direction", Int) = 0
[Toggle(BEND_ON)] _Bend("Use Bend", Int) = 0
[PowerSlider(10.0)] _Radius("Bend Radius", Range(1, 100)) = 30
_Width ("Width", Range(0.0, 10.0)) = 1.92
[PowerSlider(10.0)] _Thickness("Thickness", Range(0.01, 10)) = 1
[KeywordEnum(Off, Front, Back)] _Cull("Culling", Int) = 2
_DispTex ("Displacement Map", 2D) = "black" {}
_DispFactor("Displacement Factor", Range(0, 5.0)) = 1
_TessMinDist("Tessellation Min Distance", Range(0.1, 100.0)) = 1.0
_TessMaxDist("Tessellation Max Distance", Range(0.1, 100.0)) = 5.0
_TessFactor("Tessellation Factor", Range(0.1, 50.0)) = 10.0
}
SubShader
{
Tags { "RenderType"="Opaque" }
Cull [_Cull]
CGINCLUDE
#include "./uDD_Common.cginc"
#include "Tessellation.cginc"
half _Radius;
half _Width;
half _Thickness;
Texture2D _DispTex;
SamplerState sampler_DispTex;
half _DispFactor;
half _TessMinDist;
half _TessMaxDist;
half _TessFactor;
struct VsInput
{
float3 vertex : POSITION;
float3 normal : NORMAL;
float2 texcoord : TEXCOORD0;
};
struct HsInput
{
float4 f4Position : POS;
float3 f3Normal : NORMAL;
float2 f2TexCoord : TEXCOORD;
};
struct HsControlPointOutput
{
float3 f3Position : POS;
float3 f3Normal : NORMAL;
float2 f2TexCoord : TEXCOORD;
};
struct HsConstantOutput
{
float fTessFactor[3] : SV_TessFactor;
float fInsideTessFactor : SV_InsideTessFactor;
};
struct DsOutput
{
float4 f4Position : SV_Position;
float2 f2TexCoord : TEXCOORD0;
};
HsInput vert(VsInput i)
{
HsInput o;
o.f4Position = float4(i.vertex, 1.0);
o.f3Normal = i.normal;
o.f2TexCoord = i.texcoord;
return o;
}
[domain("tri")]
[partitioning("integer")]
[outputtopology("triangle_cw")]
[patchconstantfunc("hullConst")]
[outputcontrolpoints(3)]
HsControlPointOutput hull(InputPatch<HsInput, 3> i, uint id : SV_OutputControlPointID)
{
HsControlPointOutput o = (HsControlPointOutput)0;
o.f3Position = i[id].f4Position.xyz;
o.f3Normal = i[id].f3Normal;
o.f2TexCoord = i[id].f2TexCoord;
return o;
}
HsConstantOutput hullConst(InputPatch<HsInput, 3> i)
{
HsConstantOutput o = (HsConstantOutput)0;
float4 p0 = i[0].f4Position;
float4 p1 = i[1].f4Position;
float4 p2 = i[2].f4Position;
float4 tessFactor = UnityDistanceBasedTess(p0, p1, p2, _TessMinDist, _TessMaxDist, _TessFactor);
o.fTessFactor[0] = tessFactor.x;
o.fTessFactor[1] = tessFactor.y;
o.fTessFactor[2] = tessFactor.z;
o.fInsideTessFactor = tessFactor.w;
return o;
}
[domain("tri")]
DsOutput domain(
HsConstantOutput hsConst,
const OutputPatch<HsControlPointOutput, 3> i,
float3 bary : SV_DomainLocation)
{
DsOutput o = (DsOutput)0;
float3 f3Position =
bary.x * i[0].f3Position +
bary.y * i[1].f3Position +
bary.z * i[2].f3Position;
float3 f3Normal = normalize(
bary.x * i[0].f3Normal +
bary.y * i[1].f3Normal +
bary.z * i[2].f3Normal);
o.f2TexCoord =
bary.x * i[0].f2TexCoord +
bary.y * i[1].f2TexCoord +
bary.z * i[2].f2TexCoord;
uddBendNormal(f3Position.x, f3Normal, _Radius, _Width);
uddBendVertex(f3Position, _Radius, _Width, _Thickness);
float disp = length(_DispTex.SampleLevel(sampler_DispTex, o.f2TexCoord, 0)) * _DispFactor;
f3Position.xyz += f3Normal * disp;
o.f4Position = UnityObjectToClipPos(float4(f3Position.xyz, 1.0));
return o;
}
fixed4 frag(DsOutput i) : SV_Target
{
return uddGetScreenTexture(i.f2TexCoord);
}
ENDCG
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma hull hull
#pragma domain domain
#pragma multi_compile ___ INVERT_X
#pragma multi_compile ___ INVERT_Y
#pragma multi_compile ___ ROTATE90 ROTATE180 ROTATE270
#pragma multi_compile ___ USE_CLIP
#pragma multi_compile ___ BEND_ON
#pragma multi_compile _FORWARD_Y _FORWARD_Z
#pragma multi_compile ___ USE_GAMMA_TO_LINEAR_SPACE
ENDCG
}
}
Fallback "Unlit/Texture"
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 05df46eb51b13c84eabbdf4c53cc8db7
timeCreated: 1480072905
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -5,11 +5,11 @@ Properties
{
_Color ("Color", Color) = (1, 1, 1, 1)
_MainTex ("Texture", 2D) = "white" {}
_CursorTex ("Cursor Texture", 2D) = "white" {}
[KeywordEnum(Y, Z)] _Forward("Mesh Forward Direction", Int) = 0
[Toggle(BEND_ON)] _Bend("Use Bend", Int) = 0
[PowerSlider(10.0)] _Radius("Bend Radius", Range(1, 100)) = 30
[PowerSlider(10.0)] _Thickness("Thickness", Range(0.01, 10)) = 1
_Width("Width", Range(0.0, 10.0)) = 1.0
[KeywordEnum(Off, Front, Back)] _Cull("Culling", Int) = 2
}
@@ -33,7 +33,7 @@ half _Thickness;
v2f vert(appdata v)
{
v2f o;
uddBendVertex(v.vertex, _Radius, _Width, _Thickness);
uddBendVertex(v.vertex.xyz, _Radius, _Width, _Thickness);
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
@@ -41,7 +41,7 @@ v2f vert(appdata v)
fixed4 frag(v2f i) : SV_Target
{
return fixed4(uddGetScreenTextureWithCursor(i.uv).rgb, 1.0) * _Color;
return fixed4(uddGetScreenTexture(i.uv).rgb, 1.0) * _Color;
}
ENDCG
@@ -54,9 +54,10 @@ Pass
#pragma multi_compile ___ INVERT_X
#pragma multi_compile ___ INVERT_Y
#pragma multi_compile ___ ROTATE90 ROTATE180 ROTATE270
#pragma multi_compile ___ USE_BEND
#pragma multi_compile ___ USE_CLIP
#pragma multi_compile _BEND_OFF _BEND_Y _BEND_Z
#pragma multi_compile ___ BEND_ON
#pragma multi_compile _FORWARD_Y _FORWARD_Z
#pragma multi_compile ___ USE_GAMMA_TO_LINEAR_SPACE
ENDCG
}

View File

@@ -0,0 +1,5 @@
LIBRARY
EXPORTS
UnityPluginLoad
UnityPluginUnload

View File

@@ -6,10 +6,12 @@
#include "IUnityInterface.h"
#include "IUnityGraphicsD3D11.h"
#include "Common.h"
#include "Debug.h"
using namespace Microsoft::WRL;
extern IUnityInterfaces* g_unity;
extern std::unique_ptr<MonitorManager> g_manager;
extern std::queue<Message> g_messages;
@@ -33,7 +35,45 @@ const std::unique_ptr<MonitorManager>& GetMonitorManager()
}
LUID GetUnityAdapterLuid()
{
const auto device = GetUnity()->Get<IUnityGraphicsD3D11>()->GetDevice();
Microsoft::WRL::ComPtr<IDXGIDevice1> dxgiDevice;
if (FAILED(device->QueryInterface(IID_PPV_ARGS(&dxgiDevice)))){
Debug::Error("QueryInterface from IUnityGraphicsD3D11 to IDXGIDevice1 failed.");
return LUID();
}
Microsoft::WRL::ComPtr<IDXGIAdapter> dxgiAdapter;
if (FAILED(dxgiDevice->GetAdapter(&dxgiAdapter))) {
Debug::Error("QueryInterface from IDXGIDevice1 to IDXGIAdapter failed.");
return LUID();
}
DXGI_ADAPTER_DESC adapterDesc;
dxgiAdapter->GetDesc(&adapterDesc);
return adapterDesc.AdapterLuid;
}
void SendMessageToUnity(Message message)
{
g_messages.push(message);
}
}
ScopedTimer::ScopedTimer(TimerFuncType&& func)
: func_(func)
, start_(std::chrono::high_resolution_clock::now())
{
}
ScopedTimer::~ScopedTimer()
{
const auto end = std::chrono::high_resolution_clock::now();
const auto time = std::chrono::duration_cast<microseconds>(end - start_);
func_(time);
}

View File

@@ -1,31 +1,57 @@
#pragma once
#include <functional>
#include <memory>
#include <chrono>
#include <wrl/client.h>
// Unity interface and ID3D11Device getters
// Unity interface getter
struct IUnityInterfaces;
IUnityInterfaces* GetUnity();
// ID3D11Device (in Unity) getter
struct ID3D11Device;
Microsoft::WRL::ComPtr<ID3D11Device> GetDevice();
// Manager getter
class MonitorManager;
const std::unique_ptr<MonitorManager>& GetMonitorManager();
// Get adapter LUID to check the adapter of the monitor is same as Unity one.
LUID GetUnityAdapterLuid();
template <class T>
auto MakeUniqueWithReleaser(T* ptr)
// Releaser
class ScopedReleaser
{
const auto deleter = [](T* ptr)
{
if (ptr != nullptr) ptr->Release();
};
return std::unique_ptr<T, decltype(deleter)>(ptr, deleter);
}
public:
using ReleaseFuncType = std::function<void()>;
ScopedReleaser(ReleaseFuncType&& func) : func_(func) {}
~ScopedReleaser() { func_(); }
private:
const ReleaseFuncType func_;
};
// Timer
class ScopedTimer
{
public:
using microseconds = std::chrono::microseconds;
using TimerFuncType = std::function<void(microseconds)>;
ScopedTimer(TimerFuncType&& func);
~ScopedTimer();
private:
const TimerFuncType func_;
const std::chrono::time_point<std::chrono::steady_clock> start_;
};
// Message is pooled and fetch from Unity.
@@ -36,4 +62,116 @@ enum class Message
TextureSizeChanged = 1,
};
void SendMessageToUnity(Message message);
void SendMessageToUnity(Message message);
// Buffer
template <class T>
class Buffer
{
public:
Buffer()
{
}
Buffer(const Buffer& other)
{
value_.reset();
size_ = 0;
ExpandIfNeeded(other.size_);
memcpy_s(value_.get(), size_, other.value_.get(), other.size_);
}
Buffer<T>& operator=(const Buffer& other)
{
if (&other == this) return *this;
value_.reset();
size_ = 0;
ExpandIfNeeded(other.size_);
memcpy_s(value_.get(), size_, other.value_.get(), other.size_);
return *this;
}
~Buffer()
{
}
bool Empty() const
{
return !value_;
}
void ExpandIfNeeded(UINT size)
{
if (size > size_)
{
size_ = size;
value_ = std::make_unique<T[]>(size);
}
}
void Reset()
{
value_.reset();
size_ = 0;
}
UINT Size() const
{
return size_;
}
T* Get() const
{
return value_.get();
}
T* Get(UINT offset) const
{
return (value_.get() + offset);
}
template <class U>
U* As() const
{
return reinterpret_cast<U*>(Get());
}
template <class U>
U* As(UINT offset) const
{
return reinterpret_cast<U*>(Get(offset));
}
operator bool() const
{
return value_ != nullptr;
}
const T operator [](UINT index) const
{
if (index >= size_)
{
Debug::Error("Array index out of range: ", index, size_);
return T(0);
}
return value_[index];
}
T& operator [](UINT index)
{
if (index >= size_)
{
Debug::Error("Array index out of range: ", index, size_);
return value_[0];
}
return value_[index];
}
private:
std::unique_ptr<T[]> value_;
UINT size_ = 0;
};

View File

@@ -1,16 +1,15 @@
#include <d3d11.h>
#include <wrl/client.h>
#include "Common.h"
#include "Debug.h"
#include "MonitorManager.h"
#include "Monitor.h"
#include "Cursor.h"
#include "Debug.h"
#include "Monitor.h"
#include "Duplicator.h"
using namespace Microsoft::WRL;
Cursor::Cursor(Monitor* monitor)
: monitor_(monitor)
Cursor::Cursor()
{
}
@@ -20,7 +19,7 @@ Cursor::~Cursor()
}
void Cursor::UpdateBuffer(const DXGI_OUTDUPL_FRAME_INFO& frameInfo)
void Cursor::UpdateBuffer(Duplicator* duplicator, const DXGI_OUTDUPL_FRAME_INFO& frameInfo)
{
if (frameInfo.LastMouseUpdateTime.QuadPart == 0)
{
@@ -28,33 +27,17 @@ void Cursor::UpdateBuffer(const DXGI_OUTDUPL_FRAME_INFO& frameInfo)
}
isVisible_ = frameInfo.PointerPosition.Visible != 0;
if (isVisible_)
{
GetMonitorManager()->SetCursorMonitorId(monitor_->GetId());
}
x_ = frameInfo.PointerPosition.Position.x;
y_ = frameInfo.PointerPosition.Position.y;
timestamp_ = frameInfo.LastMouseUpdateTime;
if (!IsCursorOnParentMonitor())
{
return;
}
if (frameInfo.PointerShapeBufferSize == 0)
{
return;
}
// Increase the buffer size if needed
if (frameInfo.PointerShapeBufferSize > apiBufferSize_)
{
apiBufferSize_ = frameInfo.PointerShapeBufferSize;
apiBuffer_ = std::make_unique<BYTE[]>(apiBufferSize_);
}
if (!apiBuffer_)
buffer_.ExpandIfNeeded(frameInfo.PointerShapeBufferSize);
if (!buffer_)
{
return;
}
@@ -62,286 +45,346 @@ void Cursor::UpdateBuffer(const DXGI_OUTDUPL_FRAME_INFO& frameInfo)
// Get mouse pointer information
UINT bufferSize;
DXGI_OUTDUPL_POINTER_SHAPE_INFO shapeInfo;
const auto hr = monitor_->GetDeskDupl()->GetFramePointerShape(
apiBufferSize_,
apiBuffer_.get(),
const auto hr = duplicator->GetDuplication()->GetFramePointerShape(
buffer_.Size(),
buffer_.Get(),
&bufferSize,
&shapeInfo);
if (FAILED(hr))
{
Debug::Error("Cursor::UpdateBuffer() => GetFramePointerShape() failed.");
apiBuffer_.reset();
apiBufferSize_ = 0;
return;
buffer_.Reset();
return;
}
shapeInfo_ = shapeInfo;
}
void Cursor::UpdateTexture()
void Cursor::UpdateTexture(
Duplicator* duplicator,
const ComPtr<ID3D11Texture2D>& desktopTexture)
{
if (!IsCursorOnParentMonitor())
auto monitor = duplicator->GetMonitor();
// Check desktop texure
if (desktopTexture == nullptr)
{
Debug::Error("Cursor::UpdateTexture() => Desktop texture is null.");
return;
}
// Cursor information
const bool isMono = GetType() == DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MONOCHROME;
const bool isColorMask = GetType() == DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MASKED_COLOR;
const auto cursorImageWidth = GetWidth();
const auto cursorImageWidth = GetWidth();
const auto cursorImageHeight = GetHeight();
const auto cursorImagePitch = GetPitch();
const auto cursorImagePitch = GetPitch();
// Captured area
auto capturedImageWidth = cursorImageWidth;
auto capturedImageHeight = cursorImageHeight;
// Monitor orientation
const auto monitorRot = static_cast<DXGI_MODE_ROTATION>(monitor->GetRotation());
const auto isMonitorPortrait =
monitorRot == DXGI_MODE_ROTATION_ROTATE90 ||
monitorRot == DXGI_MODE_ROTATION_ROTATE270;
// Captured size (desktop cooridinates).
auto capturedImageWidth = !isMonitorPortrait ? cursorImageWidth : cursorImageHeight;
auto capturedImageHeight = !isMonitorPortrait ? cursorImageHeight : cursorImageWidth;
// Convert the buffer given by API into BGRA32
const UINT bgraBufferSize = cursorImageWidth * cursorImageHeight * 4;
if (bgraBufferSize > bgra32BufferSize_)
bgraBuffer_.ExpandIfNeeded(bgraBufferSize);
// Check buffers
if (!bgraBuffer_ || !buffer_)
{
bgra32BufferSize_ = bgraBufferSize;
bgra32Buffer_ = std::make_unique<BYTE[]>(bgra32BufferSize_);
Debug::Error("Cursor::UpdateTexture() => no buffer.");
return;
}
// Check buffers
if (!bgra32Buffer_ || !apiBuffer_)
{
return;
}
// If masked, copy the desktop image and merge it with masked image.
if (isMono || isColorMask)
// Desktop size
const int monitorWidth = monitor->GetWidth();
const int monitorHeight = monitor->GetHeight();
const int desktopImageWidth = !isMonitorPortrait ? monitorWidth : monitorHeight;
const int desktopImageHeight = !isMonitorPortrait ? monitorHeight : monitorWidth;
// x_, y_ are cooridinates in rotated monitor.
// desktopX, desktopY are coordinates in captured desktop image (always landscape).
int desktopX, desktopY;
switch (monitorRot)
{
const auto monitorWidth = monitor_->GetWidth();
const auto monitorHeight = monitor_->GetHeight();
const auto monitorRot = static_cast<DXGI_MODE_ROTATION>(monitor_->GetRotation());
const auto isVertical =
monitorRot == DXGI_MODE_ROTATION_ROTATE90 ||
monitorRot == DXGI_MODE_ROTATION_ROTATE270;
const auto desktopImageWidth = !isVertical ? monitorWidth : monitorHeight;
const auto desktopImageHeight = !isVertical ? monitorHeight : monitorWidth;
auto x = x_;
auto y = y_;
auto colMin = 0;
auto colMax = cursorImageWidth;
auto rowMin = 0;
auto rowMax = cursorImageHeight;
if (x < 0)
case DXGI_MODE_ROTATION_ROTATE90:
{
x = 0;
capturedImageWidth = cursorImageWidth + x_;
colMin = cursorImageWidth - capturedImageWidth;
desktopX = y_;
desktopY = (desktopImageHeight - 1) - x_ - cursorImageWidth;
break;
}
if (x + capturedImageWidth >= monitorWidth)
case DXGI_MODE_ROTATION_ROTATE180:
{
capturedImageWidth = monitorWidth - x_;
colMax = capturedImageWidth;
desktopX = (desktopImageWidth - 1) - x_ - cursorImageWidth;
desktopY = (desktopImageHeight - 1) - y_ - cursorImageHeight;
break;
}
if (y < 0)
case DXGI_MODE_ROTATION_ROTATE270:
{
y = 0;
capturedImageHeight = cursorImageHeight + y_;
rowMin = cursorImageHeight - capturedImageHeight;
desktopX = (desktopImageWidth - 1) - y_ - cursorImageHeight;
desktopY = x_;
break;
}
if (y + capturedImageHeight >= monitorHeight)
case DXGI_MODE_ROTATION_IDENTITY:
case DXGI_MODE_ROTATION_UNSPECIFIED:
default:
{
capturedImageHeight = monitorHeight - y_;
rowMax = capturedImageHeight;
desktopX = x_;
desktopY = y_;
break;
}
}
D3D11_BOX box;
box.front = 0;
box.back = 1;
// Calculate information to capture desktop image under cursor.
int cursorOffsetX = 0;
int cursorOffsetY = 0;
int capturedImageLeft = desktopX;
int capturedImageTop = desktopY;
int capturedImageRight = desktopX + capturedImageWidth;
int capturedImageBottom = desktopY + capturedImageHeight;
switch (monitorRot)
{
case DXGI_MODE_ROTATION_ROTATE90:
{
box.left = y;
box.top = monitorWidth - x - capturedImageWidth;
box.right = y + capturedImageWidth;
box.bottom = monitorWidth - x;
break;
}
case DXGI_MODE_ROTATION_ROTATE180:
{
box.left = monitorWidth - x - capturedImageWidth;
box.top = monitorHeight - y - capturedImageHeight;
box.right = monitorWidth - x;
box.bottom = monitorHeight - y;
break;
}
case DXGI_MODE_ROTATION_ROTATE270:
{
box.left = monitorHeight - y - capturedImageHeight;
box.top = x;
box.right = monitorHeight - y;
box.bottom = x + capturedImageWidth;
break;
}
case DXGI_MODE_ROTATION_IDENTITY:
case DXGI_MODE_ROTATION_UNSPECIFIED:
{
box.left = x;
box.top = y;
box.right = x + capturedImageWidth;
box.bottom = y + capturedImageHeight;
break;
}
}
if (capturedImageLeft < 0)
{
capturedImageWidth -= -desktopX;
cursorOffsetX = -desktopX;
capturedImageLeft = 0;
}
if (box.left < 0 ||
box.top < 0 ||
box.right >= static_cast<UINT>(desktopImageWidth) ||
box.bottom >= static_cast<UINT>(desktopImageHeight))
{
Debug::Error("Cursor::UpdateTexture() => box is out of area.");
Debug::Error(
" ",
"(", box.left, ", ", box.top, ")",
" ~ (", box.right, ", ", box.bottom, ") > ",
"(", desktopImageWidth, ", ", desktopImageHeight, ")");
return;
}
if (capturedImageRight >= desktopImageWidth)
{
capturedImageWidth -= capturedImageRight - desktopImageWidth;
capturedImageRight = desktopImageWidth - 1;
}
if (monitor_->GetUnityTexture() == nullptr)
{
Debug::Error("Cursor::UpdateTexture() => Monitor::GetUnityTexture() is null.");
return;
}
if (capturedImageTop < 0)
{
capturedImageHeight -= -desktopY;
cursorOffsetY = -desktopY;
capturedImageTop = 0;
}
if (capturedImageBottom >= desktopImageHeight)
{
capturedImageHeight -= capturedImageBottom - desktopImageHeight;
capturedImageBottom = desktopImageHeight - 1;
}
// Check if box is inner desktop area
if (capturedImageLeft < 0 ||
capturedImageTop < 0 ||
capturedImageRight >= desktopImageWidth ||
capturedImageBottom >= desktopImageHeight)
{
Debug::Error("Cursor::UpdateTexture() => box is out of area.");
Debug::Error(
" ",
"(", capturedImageLeft, ", ", capturedImageTop, ")",
" ~ (", capturedImageRight, ", ", capturedImageBottom, ") > ",
"(", desktopImageWidth, ", ", desktopImageHeight, ")");
return;
}
if (capturedImageWidth == 0 || capturedImageHeight == 0)
{
return;
}
capturedImageArea_ = D3D11_BOX
{
static_cast<UINT>(capturedImageLeft),
static_cast<UINT>(capturedImageTop),
0,
static_cast<UINT>(capturedImageRight),
static_cast<UINT>(capturedImageBottom),
1
};
// Create texture for capturing desktop image
ComPtr<ID3D11Texture2D> texture;
{
D3D11_TEXTURE2D_DESC desc;
desc.Width = capturedImageWidth;
desc.Height = capturedImageHeight;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.Width = capturedImageWidth;
desc.Height = capturedImageHeight;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_STAGING;
desc.BindFlags = 0;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
desc.MiscFlags = 0;
desc.Usage = D3D11_USAGE_STAGING;
desc.BindFlags = 0;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
desc.MiscFlags = 0;
ComPtr<ID3D11Texture2D> texture;
if (FAILED(GetDevice()->CreateTexture2D(&desc, nullptr, &texture)))
if (FAILED(duplicator->GetDevice()->CreateTexture2D(&desc, nullptr, &texture)))
{
Debug::Error("Cursor::UpdateTexture() => GetDevice()->CreateTexture2D() failed.");
return;
}
}
// Copy desktop image to the texture
{
ComPtr<ID3D11DeviceContext> context;
duplicator->GetDevice()->GetImmediateContext(&context);
context->CopySubresourceRegion(texture.Get(), 0, 0, 0, 0, desktopTexture.Get(), 0, &capturedImageArea_);
}
// Get mapped surface to access pixels in CPU
ComPtr<IDXGISurface> surface;
if (FAILED(texture.As(&surface)))
{
Debug::Error("Cursor::UpdateTexture() => texture.As() failed.");
return;
}
DXGI_MAPPED_RECT mappedSurface;
if (FAILED(surface->Map(&mappedSurface, DXGI_MAP_READ)))
{
Debug::Error("Cursor::UpdateTexture() => surface->Map() failed.");
return;
}
// Finally, get the desktop texture under the mouse cursor.
const auto desktop32 = reinterpret_cast<UINT*>(mappedSurface.pBits);
const UINT desktopPitch = mappedSurface.Pitch / sizeof(UINT);
// Rotate cursor image to match the monitor orientation
Buffer<BYTE> rotatedBuffer_;
rotatedBuffer_.ExpandIfNeeded(buffer_.Size());
for (int y = 0; y < capturedImageHeight; ++y)
{
for (int x = 0; x < capturedImageWidth; ++x)
{
ComPtr<ID3D11DeviceContext> context;
GetDevice()->GetImmediateContext(&context);
context->CopySubresourceRegion(texture.Get(), 0, 0, 0, 0, monitor_->GetUnityTexture(), 0, &box);
}
// Cursor coordinates
int cursorX, cursorY;
ComPtr<IDXGISurface> surface;
if (FAILED(texture.As(&surface)))
{
Debug::Error("Cursor::UpdateTexture() => texture->QueryInterface() failed.");
return;
}
DXGI_MAPPED_RECT mappedSurface;
if (FAILED(surface->Map(&mappedSurface, DXGI_MAP_READ)))
{
Debug::Error("Cursor::UpdateTexture() => surface->Map() failed.");
return;
}
// Finally, get the texture behind the mouse cursor.
const auto desktop32 = reinterpret_cast<UINT*>(mappedSurface.pBits);
const UINT desktopPitch = mappedSurface.Pitch / sizeof(UINT);
// Take the monitor orientation into consideration.
const auto getDesktop32 = [&](int col, int row)
{
switch (monitorRot)
{
case DXGI_MODE_ROTATION_ROTATE90:
return desktop32[(capturedImageWidth - 1 - col) * desktopPitch + row];
break;
case DXGI_MODE_ROTATION_ROTATE180:
return desktop32[(capturedImageHeight - 1 - row) * desktopPitch + (capturedImageWidth - 1 - col)];
break;
case DXGI_MODE_ROTATION_ROTATE270:
return desktop32[col * desktopPitch + (capturedImageHeight - 1 - row)];
break;
case DXGI_MODE_ROTATION_IDENTITY:
case DXGI_MODE_ROTATION_UNSPECIFIED:
return desktop32[row * desktopPitch + col];
break;
}
};
// Access RGBA values at the same time
auto output32 = reinterpret_cast<UINT*>(bgra32Buffer_.get());
if (isMono)
{
for (int row = rowMin, y = 0; row < rowMax; ++row, ++y)
switch (monitorRot)
{
for (int col = colMin, x = 0; col < colMax; ++col, ++x)
case DXGI_MODE_ROTATION_ROTATE90:
{
BYTE mask = 0b10000000 >> (col % 8);
const BYTE andMask = apiBuffer_[col / 8 + row * cursorImagePitch] & mask;
const BYTE xorMask = apiBuffer_[col / 8 + (row + capturedImageHeight) * cursorImagePitch] & mask;
const UINT andMask32 = andMask ? 0xFFFFFFFF : 0x00000000;
const UINT xorMask32 = xorMask ? 0xFFFFFFFF : 0x00000000;
output32[row * cursorImageWidth + col] = (getDesktop32(x, y) & andMask32) ^ xorMask32;
cursorX = (cursorImageWidth - 1) - (y + cursorOffsetY);
cursorY = (x + cursorOffsetX);
break;
}
case DXGI_MODE_ROTATION_ROTATE180:
{
cursorX = (cursorImageWidth - 1) - (x + cursorOffsetX);
cursorY = (cursorImageHeight - 1) - (y + cursorOffsetY);
break;
}
case DXGI_MODE_ROTATION_ROTATE270:
{
cursorX = (y + cursorOffsetY);
cursorY = (cursorImageHeight - 1) - (x + cursorOffsetX);
break;
}
case DXGI_MODE_ROTATION_IDENTITY:
case DXGI_MODE_ROTATION_UNSPECIFIED:
default:
{
cursorX = (x + cursorOffsetX);
cursorY = (y + cursorOffsetY);
break;
}
}
}
else // DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MASKED_COLOR
{
const auto buffer32 = reinterpret_cast<UINT*>(apiBuffer_.get());
for (int row = rowMin, y = 0; row < rowMax; ++row, ++y)
const auto outputIndex = y * capturedImageWidth + x;
const auto desktopIndex = y * desktopPitch + x;
const auto cursorIndex = cursorY * cursorImageWidth + cursorX;
const auto buffer32 = buffer_.As<UINT>();
auto output32 = bgraBuffer_.As<UINT>();
switch (GetType())
{
for (int col = colMin, x = 0; col < colMax; ++col, ++x)
case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MONOCHROME:
{
const int i = col + row * cursorImageWidth;
const int j = col + row * cursorImagePitch / sizeof(UINT);
UINT mask = 0xFF000000 & buffer32[j];
BYTE mask = 0b10000000 >> (cursorX % 8);
const BYTE andMask = buffer_[cursorX / 8 + cursorY * cursorImagePitch] & mask;
const BYTE xorMask = buffer_[cursorX / 8 + (cursorY + cursorImageHeight) * cursorImagePitch] & mask;
const UINT andMask32 = andMask ? 0xFFFFFFFF : 0x00000000;
const UINT xorMask32 = xorMask ? 0xFFFFFFFF : 0x00000000;
output32[outputIndex] = (desktop32[desktopIndex] & andMask32) ^ xorMask32;
break;
}
case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MASKED_COLOR:
{
UINT mask = 0xFF000000 & buffer32[cursorIndex];
if (mask)
{
output32[i] = (getDesktop32(x, y) ^ buffer32[j]) | 0xFF000000;
output32[outputIndex] = (desktop32[desktopIndex] ^ buffer32[cursorIndex]) | 0xFF000000;
}
else
{
output32[i] = buffer32[j] | 0xFF000000;
output32[outputIndex] = buffer32[cursorIndex] | 0xFF000000;
}
break;
}
case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_COLOR:
{
const auto desktop = reinterpret_cast<BYTE*>(&desktop32[desktopIndex]);
const auto desktopB = desktop[0];
const auto desktopG = desktop[1];
const auto desktopR = desktop[2];
const auto desktopA = desktop[3];
const auto cursor = buffer_.Get(cursorIndex * 4);
const auto cursorB = cursor[0];
const auto cursorG = cursor[1];
const auto cursorR = cursor[2];
const auto cursorA = cursor[3];
const auto a0 = cursorA / 255.f;
const auto a1 = 1.f - a0;
auto output = reinterpret_cast<BYTE*>(&output32[outputIndex]);
output[0] = static_cast<BYTE>(cursorB * a0 + desktopB * a1);
output[1] = static_cast<BYTE>(cursorG * a0 + desktopG * a1);
output[2] = static_cast<BYTE>(cursorR * a0 + desktopR * a1);
output[3] = desktopA;
break;
}
default:
{
Debug::Error("Cursor::UpdateTexture() => Unknown cursor type");
return;
}
}
}
}
if (FAILED(surface->Unmap()))
{
return;
}
}
else // DXGI_OUTDUPL_POINTER_SHAPE_TYPE_COLOR
if (FAILED(surface->Unmap()))
{
auto output32 = reinterpret_cast<UINT*>(bgra32Buffer_.get());
const auto buffer32 = reinterpret_cast<UINT*>(apiBuffer_.get());
for (int i = 0; i < cursorImageWidth * cursorImageHeight; ++i)
{
output32[i] = buffer32[i];
}
Debug::Error("Cursor::UpdateTexture() => surface->Unmap() failed.");
return;
}
}
void Cursor::Draw(const Microsoft::WRL::ComPtr<ID3D11Texture2D>& texture)
{
if (texture == nullptr)
{
Debug::Error("Cursor::UpdateTexture() => Desktop texture is null.");
return;
}
const auto capturedImageWidth = capturedImageArea_.right - capturedImageArea_.left;
ComPtr<ID3D11DeviceContext> context;
GetDevice()->GetImmediateContext(&context);
context->UpdateSubresource(texture.Get(), 0, &capturedImageArea_, bgraBuffer_.Get(), capturedImageWidth * 4, 0);
}
void Cursor::GetTexture(ID3D11Texture2D* texture)
{
if (bgra32Buffer_ == nullptr)
if (!bgraBuffer_)
{
Debug::Error("Cursor::GetTexture() => bgra32Buffer is null.");
return;
@@ -368,7 +411,7 @@ void Cursor::GetTexture(ID3D11Texture2D* texture)
ComPtr<ID3D11DeviceContext> context;
GetDevice()->GetImmediateContext(&context);
context->UpdateSubresource(texture, 0, nullptr, bgra32Buffer_.get(), GetWidth() * 4, 0);
context->UpdateSubresource(texture, 0, nullptr, bgraBuffer_.Get(), GetWidth() * 4, 0);
}
@@ -413,10 +456,4 @@ int Cursor::GetPitch() const
int Cursor::GetType() const
{
return shapeInfo_.Type;
}
bool Cursor::IsCursorOnParentMonitor() const
{
return GetMonitorManager()->GetCursorMonitorId() == monitor_->GetId();
}

View File

@@ -2,17 +2,25 @@
#include <d3d11.h>
#include <dxgi1_2.h>
#include <wrl/client.h>
#include <memory>
class Monitor;
#include "Common.h"
class Duplicator;
class Cursor
{
public:
explicit Cursor(Monitor* monitor);
explicit Cursor();
~Cursor();
void UpdateBuffer(const DXGI_OUTDUPL_FRAME_INFO& frameInfo);
void UpdateTexture();
void UpdateBuffer(
Duplicator* duplicator,
const DXGI_OUTDUPL_FRAME_INFO& frameInfo);
void UpdateTexture(
Duplicator* duplicator,
const Microsoft::WRL::ComPtr<ID3D11Texture2D>& desktopTexture);
void Draw(const Microsoft::WRL::ComPtr<ID3D11Texture2D>& texture);
void GetTexture(ID3D11Texture2D* texture);
bool IsVisible() const;
@@ -24,16 +32,12 @@ public:
int GetType() const;
private:
bool IsCursorOnParentMonitor() const;
Monitor* monitor_;
bool isVisible_ = false;
int x_ = -1;
int y_ = -1;
std::unique_ptr<BYTE[]> apiBuffer_ = nullptr;
UINT apiBufferSize_ = 0;
std::unique_ptr<BYTE[]> bgra32Buffer_ = nullptr;
UINT bgra32BufferSize_ = 0;
Buffer<BYTE> buffer_;
Buffer<BYTE> bgraBuffer_;
DXGI_OUTDUPL_POINTER_SHAPE_INFO shapeInfo_;
LARGE_INTEGER timestamp_;
D3D11_BOX capturedImageArea_;
};

View File

@@ -4,15 +4,21 @@
#include "Debug.h"
decltype(Debug::mode_) Debug::mode_ = Debug::Mode::File;
decltype(Debug::logFunc_) Debug::logFunc_ = nullptr;
decltype(Debug::errFunc_) Debug::errFunc_ = nullptr;
decltype(Debug::fs_) Debug::fs_;
decltype(Debug::ss_) Debug::ss_;
decltype(Debug::isInitialized_) Debug::isInitialized_ = false;
decltype(Debug::mode_) Debug::mode_ = Debug::Mode::File;
decltype(Debug::logFunc_) Debug::logFunc_ = nullptr;
decltype(Debug::errFunc_) Debug::errFunc_ = nullptr;
decltype(Debug::fs_) Debug::fs_;
decltype(Debug::ss_) Debug::ss_;
decltype(Debug::mutex_) Debug::mutex_;
void Debug::Initialize()
{
if (isInitialized_) return;
isInitialized_ = true;
if (mode_ == Mode::File)
{
fs_.open("uDesktopDuplication.log");
@@ -23,6 +29,9 @@ void Debug::Initialize()
void Debug::Finalize()
{
if (!isInitialized_) return;
isInitialized_ = false;
if (mode_ == Mode::File)
{
Debug::Log("Stop");

View File

@@ -1,9 +1,18 @@
#pragma once
#include <time.h>
#include <fstream>
#include <sstream>
#include <mutex>
#include "Common.h"
#include "IUnityInterface.h"
// Debug flag
#define UDD_DEBUG_ON
// Logging
class Debug
{
@@ -64,8 +73,12 @@ private:
{
switch (level)
{
case Level::Log : logFunc_(ss_.str().c_str()); break;
case Level::Error : errFunc_(ss_.str().c_str()); break;
case Level::Log :
if (logFunc_) logFunc_(ss_.str().c_str());
break;
case Level::Error :
if (errFunc_) errFunc_(ss_.str().c_str());
break;
}
}
break;
@@ -103,6 +116,7 @@ public:
template <class Arg, class... RestArgs>
static void Log(Arg&& arg, RestArgs&&... restArgs)
{
std::lock_guard<std::mutex> lock(mutex_);
Output("[uDD::Log]");
OutputTime();
Output(" ");
@@ -112,6 +126,7 @@ public:
template <class Arg, class... RestArgs>
static void Error(Arg&& arg, RestArgs&&... restArgs)
{
std::lock_guard<std::mutex> lock(mutex_);
Output("[uDD::Err]");
OutputTime();
Output(" ");
@@ -119,9 +134,28 @@ public:
}
private:
static bool isInitialized_;
static Mode mode_;
static std::ofstream fs_;
static std::ostringstream ss_;
static DebugLogFuncPtr logFunc_;
static DebugLogFuncPtr errFunc_;
};
static std::mutex mutex_;
};
#ifdef UDD_DEBUG_ON
#define UDD_FUNCTION_SCOPE_TIMER \
ScopedTimer _timer_##__COUNTER__([](std::chrono::microseconds us) \
{ \
Debug::Log(__FUNCTION__, "@", __FILE__, ":", __LINE__, " => ", us.count(), " [us]"); \
});
#define UDD_SCOPE_TIMER(Name) \
ScopedTimer _timer_##__COUNTER__([](std::chrono::microseconds us) \
{ \
Debug::Log(#Name, " => ", us.count(), " [us]"); \
});
#else
#define UDD_FUNCTION_SCOPE_TIMER
#define UDD_SCOPE_TIMER(Name)
#endif

View File

@@ -0,0 +1,97 @@
#pragma once
#include <queue>
#include <d3d11.h>
#include "IUnityInterface.h"
#include "IUnityGraphicsD3D11.h"
#include "Device.h"
#include "Debug.h"
#include "Common.h"
#pragma comment(lib, "d3d11.lib")
using namespace Microsoft::WRL;
IsolatedD3D11Device::IsolatedD3D11Device()
{
}
IsolatedD3D11Device::~IsolatedD3D11Device()
{
}
HRESULT IsolatedD3D11Device::Create(const ComPtr<IDXGIAdapter>& adapter)
{
const auto driverType = adapter ?
D3D_DRIVER_TYPE_UNKNOWN :
D3D_DRIVER_TYPE_HARDWARE;
const auto flags =
D3D11_CREATE_DEVICE_BGRA_SUPPORT; // D2D Compatible
// | D3D11_CREATE_DEVICE_VIDEO_SUPPORT // MediaFoundation
const D3D_FEATURE_LEVEL featureLevelsRequested[] =
{
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
D3D_FEATURE_LEVEL_9_3,
D3D_FEATURE_LEVEL_9_2,
D3D_FEATURE_LEVEL_9_1
};
const UINT numLevelsRequested = sizeof(featureLevelsRequested) / sizeof(D3D_FEATURE_LEVEL);
D3D_FEATURE_LEVEL featureLevelsSupported;
return D3D11CreateDevice(
adapter.Get(),
driverType,
nullptr,
flags,
featureLevelsRequested,
numLevelsRequested,
D3D11_SDK_VERSION,
&device_,
&featureLevelsSupported,
nullptr);
}
ComPtr<ID3D11Device> IsolatedD3D11Device::GetDevice()
{
return device_;
}
Microsoft::WRL::ComPtr<ID3D11Texture2D> IsolatedD3D11Device::GetCompatibleSharedTexture(
const ComPtr<ID3D11Texture2D>& src)
{
D3D11_TEXTURE2D_DESC srcDesc;
src->GetDesc(&srcDesc);
// check if the format and size of the current texture are same as the source one
if (cachedSharedTexture_)
{
D3D11_TEXTURE2D_DESC targetDesc;
cachedSharedTexture_->GetDesc(&targetDesc);
if (targetDesc.Format == srcDesc.Format &&
targetDesc.Width == srcDesc.Width &&
targetDesc.Height == srcDesc.Height)
{
return cachedSharedTexture_;
}
}
// for sharing this texture with unity device
srcDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
if (FAILED(device_->CreateTexture2D(&srcDesc, nullptr, &cachedSharedTexture_)))
{
Debug::Error("IsolatedD3D11Device::GetCompatibleSharedTexture() => Creating shared texture failed.");
return nullptr;
}
return cachedSharedTexture_;
}

View File

@@ -0,0 +1,25 @@
#pragma once
#include <atomic>
#include <vector>
#include <memory>
#include <d3d11.h>
#include <wrl/client.h>
// Thraed safe self created ID3D11Device from specified adapter
class IsolatedD3D11Device
{
public:
IsolatedD3D11Device();
~IsolatedD3D11Device();
HRESULT Create(const Microsoft::WRL::ComPtr<IDXGIAdapter>& adapter);
Microsoft::WRL::ComPtr<ID3D11Device> GetDevice();
Microsoft::WRL::ComPtr<ID3D11Texture2D> GetCompatibleSharedTexture(
const Microsoft::WRL::ComPtr<ID3D11Texture2D>& src);
private:
Microsoft::WRL::ComPtr<ID3D11Device> device_;
Microsoft::WRL::ComPtr<ID3D11Texture2D> cachedSharedTexture_;
};

View File

@@ -0,0 +1,468 @@
#pragma once
#include <chrono>
#include "Duplicator.h"
#include "Monitor.h"
#include "MonitorManager.h"
#include "Cursor.h"
#include "Device.h"
#include "Debug.h"
#include "IUnityInterface.h"
#include "IUnityGraphicsD3D11.h"
using namespace Microsoft::WRL;
Duplicator::Duplicator(Monitor* monitor)
: monitor_(monitor)
{
InitializeDevice();
InitializeDuplication();
CheckUnityAdapter();
}
Duplicator::~Duplicator()
{
Stop();
}
void Duplicator::InitializeDevice()
{
device_ = std::make_shared<IsolatedD3D11Device>();
if (FAILED(device_->Create(monitor_->GetAdapter())))
{
Debug::Error("Monitor::Initialize() => IsolatedD3D11Device::Create() failed.");
state_ = State::Unknown;
}
}
void Duplicator::InitializeDuplication()
{
ComPtr<IDXGIOutput1> output1;
if (FAILED(monitor_->GetOutput().As(&output1)))
{
return;
}
auto hr = output1->DuplicateOutput(device_->GetDevice().Get(), &dupl_);
switch (hr)
{
case S_OK:
{
state_ = State::Ready;
const auto rot = static_cast<DXGI_MODE_ROTATION>(monitor_->GetRotation());
Debug::Log("Duplicator::Initialize() => OK.");
Debug::Log(" ID : ", monitor_->GetId());
Debug::Log(" Size : (", monitor_->GetWidth(), ", ", monitor_->GetHeight(), ")");
Debug::Log(" DPI : (", monitor_->GetDpiX(), ", ", monitor_->GetDpiY(), ")");
Debug::Log(" Rot : ",
rot == DXGI_MODE_ROTATION_IDENTITY ? "Landscape" :
rot == DXGI_MODE_ROTATION_ROTATE90 ? "Portrait" :
rot == DXGI_MODE_ROTATION_ROTATE180 ? "Landscape (flipped)" :
rot == DXGI_MODE_ROTATION_ROTATE270 ? "Portrait (flipped)" :
"Unspecified");
break;
}
case E_INVALIDARG:
{
state_ = State::InvalidArg;
Debug::Error("Duplicator::Initialize() => Invalid arguments.");
break;
}
case E_ACCESSDENIED:
{
// For example, when the user presses Ctrl + Alt + Delete and the screen
// switches to admin screen, this error occurs.
state_ = State::AccessDenied;
Debug::Error("Duplicator::Initialize() => Access denied.");
break;
}
case DXGI_ERROR_UNSUPPORTED:
{
// If the display adapter on the computer is running under the Microsoft Hybrid system,
// this error occurs.
state_ = State::Unsupported;
Debug::Error("Duplicator::Initialize() => Unsupported display.");
break;
}
case DXGI_ERROR_NOT_CURRENTLY_AVAILABLE:
{
// When other application use Desktop Duplication API, this error occurs.
state_ = State::CurrentlyNotAvailable;
Debug::Error("Duplicator::Initialize() => Currently not available.");
break;
}
case DXGI_ERROR_SESSION_DISCONNECTED:
{
state_ = State::SessionDisconnected;
Debug::Error("Duplicator::Initialize() => Session disconnected.");
break;
}
default:
{
state_ = State::Unknown;
Debug::Error("Duplicator::Render() => Unknown Error.");
break;
}
}
}
void Duplicator::CheckUnityAdapter()
{
DXGI_ADAPTER_DESC desc;
monitor_->GetAdapter()->GetDesc(&desc);
const auto unityAdapterLuid = GetUnityAdapterLuid();
const auto isUnityAdapter =
(desc.AdapterLuid.LowPart == unityAdapterLuid.LowPart) &&
(desc.AdapterLuid.HighPart == unityAdapterLuid.HighPart);
if (!isUnityAdapter)
{
Debug::Error("Duplicator::CheckUnityAdapter() => The adapter is not same as Unity, and now this case is not supported.");
state_ = State::Unsupported;
}
}
void Duplicator::Start()
{
if (state_ != State::Ready) return;
Stop();
thread_ = std::thread([this]
{
using namespace std::chrono;
state_ = State::Running;
shouldRun_ = true;
while (shouldRun_)
{
const auto frameRate = GetMonitorManager()->GetFrameRate();
const UINT frameMicroSeconds = 1000000 / frameRate;
const UINT frameMilliSeconds = 1000 / frameRate;
ScopedTimer timer([frameMicroSeconds] (microseconds us)
{
const auto waitTime = microseconds(frameMicroSeconds) - us;
if (waitTime > microseconds::zero())
{
std::this_thread::sleep_for(waitTime);
}
});
const auto timeout = static_cast<UINT>(frameMilliSeconds);
Duplicate(timeout);
if (state_ != State::Running)
{
break;
}
}
if (state_ == State::Running)
{
state_ = State::Ready;
}
});
}
void Duplicator::Stop()
{
shouldRun_ = false;
if (thread_.joinable())
{
thread_.join();
}
}
bool Duplicator::IsRunning() const
{
return state_ == State::Running;
}
bool Duplicator::IsError() const
{
return
state_ != State::Ready &&
state_ != State::Running;
}
Duplicator::State Duplicator::GetState() const
{
return state_;
}
Monitor* Duplicator::GetMonitor() const
{
return monitor_;
}
Microsoft::WRL::ComPtr<ID3D11Device> Duplicator::GetDevice()
{
return device_->GetDevice();
}
ComPtr<IDXGIOutputDuplication> Duplicator::GetDuplication()
{
return dupl_;
}
const Duplicator::Frame& Duplicator::GetLastFrame() const
{
std::lock_guard<std::mutex> lock(mutex_);
return lastFrame_;
}
void Duplicator::Duplicate(UINT timeout)
{
if (!dupl_ || !device_) return;
Release();
ComPtr<IDXGIResource> resource;
DXGI_OUTDUPL_FRAME_INFO frameInfo;
const auto hr = dupl_->AcquireNextFrame(timeout, &frameInfo, &resource);
if (FAILED(hr))
{
switch (hr)
{
case DXGI_ERROR_ACCESS_LOST:
{
// If any monitor setting has changed (e.g. monitor size has changed),
// it is necessary to re-initialize monitors.
Debug::Log("Duplicator::Duplicate() => DXGI_ERROR_ACCESS_LOST.");
state_ = State::AccessLost;
break;
}
case DXGI_ERROR_WAIT_TIMEOUT:
{
// This often occurs when timeout value is small and it is not problem.
// Debug::Log("Duplicator::Duplicate() => DXGI_ERROR_WAIT_TIMEOUT.");
break;
}
case DXGI_ERROR_INVALID_CALL:
{
Debug::Error("Duplicator::Duplicate() => DXGI_ERROR_INVALID_CALL.");
break;
}
case E_INVALIDARG:
{
Debug::Error("Duplicator::Duplicate() => E_INVALIDARG.");
break;
}
default:
{
state_ = State::Unknown;
Debug::Error("Duplicator::Duplicate() => Unknown Error.");
break;
}
}
return;
}
isFrameAcquired_ = true;
ComPtr<ID3D11Texture2D> texture;
if (FAILED(resource.As(&texture)))
{
Debug::Error("Duplicator::Duplicate() => IDXGIResource could not be converted to ID3D11Texture2D.");
return;
}
auto sharedTexture = device_->GetCompatibleSharedTexture(texture);
if (!sharedTexture)
{
Debug::Error("Duplicator::Duplicate() => Shared texture is null.");
return;
}
{
ComPtr<ID3D11DeviceContext> context;
device_->GetDevice()->GetImmediateContext(&context);
context->CopyResource(sharedTexture.Get(), texture.Get());
}
UpdateCursor(sharedTexture, frameInfo);
UpdateMetadata(frameInfo.TotalMetadataBufferSize);
{
std::lock_guard<std::mutex> lock(mutex_);
lastFrame_ = Frame
{
lastFrameId_++,
sharedTexture,
frameInfo,
metaData_
};
}
}
void Duplicator::Release()
{
if (!isFrameAcquired_) return;
const auto hr = dupl_->ReleaseFrame();
if (FAILED(hr))
{
switch (hr)
{
case DXGI_ERROR_ACCESS_LOST:
{
Debug::Log("Duplicator::Duplicate() => DXGI_ERROR_ACCESS_LOST.");
state_ = State::AccessLost;
break;
}
case DXGI_ERROR_INVALID_CALL:
{
Debug::Error("Duplicator::Duplicate() => DXGI_ERROR_INVALID_CALL.");
break;
}
default:
{
state_ = State::Unknown;
Debug::Error("Duplicator::Duplicate() => Unknown Error.");
break;
}
}
}
isFrameAcquired_ = false;
}
void Duplicator::UpdateCursor(
const ComPtr<ID3D11Texture2D>& texture,
const DXGI_OUTDUPL_FRAME_INFO& frameInfo)
{
auto& manager = GetMonitorManager();
if (frameInfo.PointerPosition.Visible)
{
manager->SetCursorMonitorId(monitor_->GetId());
}
if (monitor_->GetId() == manager->GetCursorMonitorId())
{
auto cursor = manager->GetCursor();
cursor->UpdateBuffer(this, frameInfo);
cursor->UpdateTexture(this, texture);
}
}
void Duplicator::UpdateMetadata(UINT totalBufferSize)
{
metaData_.buffer.ExpandIfNeeded(totalBufferSize);
if (!metaData_.buffer.Empty())
{
UpdateMoveRects();
UpdateDirtyRects();
}
}
void Duplicator::UpdateMoveRects()
{
const auto hr = dupl_->GetFrameMoveRects(
metaData_.buffer.Size(),
metaData_.buffer.As<DXGI_OUTDUPL_MOVE_RECT>(),
&metaData_.moveRectSize);
if (FAILED(hr))
{
switch (hr)
{
case DXGI_ERROR_ACCESS_LOST:
{
Debug::Log("Duplicator::UpdateMoveRects() => DXGI_ERROR_ACCESS_LOST.");
break;
}
case DXGI_ERROR_MORE_DATA:
{
Debug::Error("Duplicator::UpdateMoveRects() => DXGI_ERROR_MORE_DATA.");
break;
}
case DXGI_ERROR_INVALID_CALL:
{
Debug::Error("Duplicator::UpdateMoveRects() => DXGI_ERROR_INVALID_CALL.");
break;
}
case E_INVALIDARG:
{
Debug::Error("Duplicator::UpdateMoveRects() => E_INVALIDARG.");
break;
}
default:
{
Debug::Error("Duplicator::UpdateMoveRects() => Unknown Error.");
break;
}
}
return;
}
}
void Duplicator::UpdateDirtyRects()
{
const auto hr = dupl_->GetFrameDirtyRects(
metaData_.buffer.Size() - metaData_.moveRectSize,
metaData_.buffer.As<RECT>(metaData_.moveRectSize /* offset */),
&metaData_.dirtyRectSize);
if (FAILED(hr))
{
switch (hr)
{
case DXGI_ERROR_ACCESS_LOST:
{
Debug::Log("Duplicator::UpdateDirtyRects() => DXGI_ERROR_ACCESS_LOST.");
break;
}
case DXGI_ERROR_MORE_DATA:
{
Debug::Error("Duplicator::UpdateDirtyRects() => DXGI_ERROR_MORE_DATA.");
break;
}
case DXGI_ERROR_INVALID_CALL:
{
Debug::Error("Duplicator::UpdateDirtyRects() => DXGI_ERROR_INVALID_CALL.");
break;
}
case E_INVALIDARG:
{
Debug::Error("Duplicator::UpdateDirtyRects() => E_INVALIDARG.");
break;
}
default:
{
Debug::Error("Duplicator::UpdateDirtyRects() => Unknown Error.");
break;
}
}
return;
}
}

View File

@@ -0,0 +1,94 @@
#pragma once
#include <d3d11.h>
#include <dxgi1_2.h>
#include <memory>
#include <atomic>
#include <thread>
#include <mutex>
#include <wrl/client.h>
#include "Common.h"
class Monitor;
enum class DuplicatorState
{
NotSet = -1,
Ready = 0,
Running = 1,
InvalidArg = 2,
AccessDenied = 3,
Unsupported = 4,
CurrentlyNotAvailable = 5,
SessionDisconnected = 6,
AccessLost = 7,
TextureSizeInconsistent = 8,
Unknown = 999,
};
class Duplicator
{
public:
using State = DuplicatorState;
struct Metadata
{
Buffer<BYTE> buffer;
UINT moveRectSize = 0;
UINT dirtyRectSize = 0;
};
struct Frame
{
UINT id;
Microsoft::WRL::ComPtr<ID3D11Texture2D> texture;
DXGI_OUTDUPL_FRAME_INFO info;
Metadata metaData;
};
explicit Duplicator(Monitor* monitor);
~Duplicator();
void Start();
void Stop();
bool IsRunning() const;
bool IsError() const;
State GetState() const;
Monitor* GetMonitor() const;
Microsoft::WRL::ComPtr<ID3D11Device> GetDevice();
Microsoft::WRL::ComPtr<IDXGIOutputDuplication> GetDuplication();
const Frame& GetLastFrame() const;
private:
void InitializeDevice();
void InitializeDuplication();
void CheckUnityAdapter();
void Duplicate(UINT timeout);
void Release();
void UpdateCursor(
const Microsoft::WRL::ComPtr<ID3D11Texture2D>& texture,
const DXGI_OUTDUPL_FRAME_INFO& frameInfo);
void UpdateMetadata(UINT totalBufferSize);
void UpdateMoveRects();
void UpdateDirtyRects();
Monitor* monitor_ = nullptr;
std::atomic<State> state_ = State::Ready;
std::shared_ptr<class IsolatedD3D11Device> device_;
Microsoft::WRL::ComPtr<IDXGIOutputDuplication> dupl_;
Frame lastFrame_;
UINT lastFrameId_ = 0;
bool isFrameAcquired_ = false;
volatile bool shouldRun_ = false;
std::thread thread_;
mutable std::mutex mutex_;
Metadata metaData_;
};

View File

@@ -1,200 +1,131 @@
#include <d3d11.h>
#include <ShellScalingAPI.h>
#include "Common.h"
#include <queue>
#include "Monitor.h"
#include "Duplicator.h"
#include "Debug.h"
#include "Cursor.h"
#include "MonitorManager.h"
#include "Monitor.h"
#include "Device.h"
using namespace Microsoft::WRL;
Monitor::Monitor(int id)
: id_(id)
, cursor_(std::make_unique<Cursor>(this))
{
ZeroMemory(&monitorInfo_, sizeof(monitorInfo_));
}
Monitor::~Monitor()
{
if (deskDupl_)
{
deskDupl_->Release();
deskDupl_ = nullptr;
}
duplicator_->Stop();
}
void Monitor::Initialize(IDXGIOutput* output)
void Monitor::Initialize(
const ComPtr<IDXGIAdapter> &adapter,
const ComPtr<IDXGIOutput> &output
)
{
if (FAILED(output->GetDesc(&outputDesc_)))
adapter_ = adapter;
output_ = output;
if (FAILED(output->GetDesc(&outputDesc_)))
{
Debug::Error("Monitor::Initialize() => IDXGIOutput::GetDesc() failed.");
return;
}
monitorInfo_.cbSize = sizeof(MONITORINFOEX);
if (!GetMonitorInfo(outputDesc_.Monitor, &monitorInfo_))
{
Debug::Error("Monitor::Initialize() => GetMonitorInfo() failed.");
return;
}
else
{
const auto rect = monitorInfo_.rcMonitor;
width_ = rect.right - rect.left;
height_ = rect.bottom - rect.top;
}
if (FAILED(GetDpiForMonitor(outputDesc_.Monitor, MDT_RAW_DPI, &dpiX_, &dpiY_)))
{
Debug::Error("Monitor::Initialize() => GetDpiForMonitor() failed.");
// DPI is set as -1, so the application has to use the appropriate value.
}
duplicator_ = std::make_shared<Duplicator>(this);
}
void Monitor::Finalize()
{
StopCapture();
}
void Monitor::Render()
{
const auto& frame = duplicator_->GetLastFrame();
if (frame.id == lastFrameId_) return;
lastFrameId_ = frame.id;
if (unityTexture_ == nullptr)
{
Debug::Error("Monitor::Initialize() => IDXGIOutput::GetDesc() failed.");
Debug::Error("Monitor::Render() => Target texture has not been set yet..");
return;
}
monitorInfo_.cbSize = sizeof(MONITORINFOEX);
if (!GetMonitorInfo(outputDesc_.Monitor, &monitorInfo_))
D3D11_TEXTURE2D_DESC srcDesc, dstDesc;
frame.texture->GetDesc(&srcDesc);
unityTexture_->GetDesc(&dstDesc);
if (srcDesc.Width != dstDesc.Width ||
srcDesc.Height != dstDesc.Height)
{
Debug::Error("Monitor::Initialize() => GetMonitorInfo() failed.");
Debug::Error("Monitor::Render() => Texture sizes are defferent.");
Debug::Error(" Source : (", srcDesc.Width, ", ", srcDesc.Height, ")");
Debug::Error(" Dest : (", dstDesc.Width, ", ", dstDesc.Height, ")");
return;
}
else
{
const auto rect = monitorInfo_.rcMonitor;
width_ = rect.right - rect.left;
height_ = rect.bottom - rect.top;
ComPtr<ID3D11DeviceContext> context;
GetDevice()->GetImmediateContext(&context);
context->CopyResource(unityTexture_, frame.texture.Get());
auto& manager = GetMonitorManager();
if (id_ == manager->GetCursorMonitorId())
{
manager->GetCursor()->Draw(unityTexture_);
}
}
if (FAILED(GetDpiForMonitor(outputDesc_.Monitor, MDT_RAW_DPI, &dpiX_, &dpiY_)))
{
Debug::Error("Monitor::Initialize() => GetDpiForMonitor() failed.");
return;
}
if (UseGetPixels())
{
CopyTextureFromGpuToCpu(unityTexture_);
}
auto output1 = reinterpret_cast<IDXGIOutput1*>(output);
switch (output1->DuplicateOutput(GetDevice().Get(), &deskDupl_))
hasBeenUpdated_ = true;
}
void Monitor::StartCapture()
{
if (duplicator_->GetState() == DuplicatorState::Ready)
{
case S_OK:
{
state_ = State::Available;
Debug::Log("Monitor::Initialize() => OK.");
Debug::Log(" ID : ", GetId());
Debug::Log(" Size : (", GetWidth(), ", ", GetHeight(), ")");
Debug::Log(" DPI : (", GetDpiX(), ", ", GetDpiY(), ")");
break;
}
case E_INVALIDARG:
{
state_ = State::InvalidArg;
Debug::Error("Monitor::Initialize() => Invalid arguments.");
break;
}
case E_ACCESSDENIED:
{
// For example, when the user presses Ctrl + Alt + Delete and the screen
// switches to admin screen, this error occurs.
state_ = State::AccessDenied;
Debug::Error("Monitor::Initialize() => Access denied.");
break;
}
case DXGI_ERROR_UNSUPPORTED:
{
// If the display adapter on the computer is running under the Microsoft Hybrid system,
// this error occurs.
state_ = State::Unsupported;
Debug::Error("Monitor::Initialize() => Unsupported display.");
break;
}
case DXGI_ERROR_NOT_CURRENTLY_AVAILABLE:
{
// When other application use Desktop Duplication API, this error occurs.
state_ = State::CurrentlyNotAvailable;
Debug::Error("Monitor::Initialize() => Currently not available.");
break;
}
case DXGI_ERROR_SESSION_DISCONNECTED:
{
state_ = State::SessionDisconnected;
Debug::Error("Monitor::Initialize() => Session disconnected.");
break;
}
default:
{
state_ = State::Unknown;
Debug::Error("Monitor::Render() => Unknown Error.");
break;
}
duplicator_->Start();
}
}
void Monitor::Render(UINT timeout)
void Monitor::StopCapture()
{
if (!deskDupl_) return;
ComPtr<IDXGIResource> resource;
DXGI_OUTDUPL_FRAME_INFO frameInfo;
const auto hr = deskDupl_->AcquireNextFrame(timeout, &frameInfo, &resource);
if (FAILED(hr))
{
switch (hr)
{
case DXGI_ERROR_ACCESS_LOST:
{
// If any monitor setting has changed (e.g. monitor size has changed),
// it is necessary to re-initialize monitors.
Debug::Log("Monitor::Render() => DXGI_ERROR_ACCESS_LOST.");
state_ = State::AccessLost;
break;
}
case DXGI_ERROR_WAIT_TIMEOUT:
{
// This often occurs when timeout value is small and it is not problem.
// Debug::Log("Monitor::Render() => DXGI_ERROR_WAIT_TIMEOUT.");
break;
}
case DXGI_ERROR_INVALID_CALL:
{
Debug::Error("Monitor::Render() => DXGI_ERROR_INVALID_CALL.");
break;
}
case E_INVALIDARG:
{
Debug::Error("Monitor::Render() => E_INVALIDARG.");
break;
}
default:
{
state_ = State::Unknown;
Debug::Error("Monitor::Render() => Unknown Error.");
break;
}
}
return;
}
if (unityTexture_)
{
ID3D11Texture2D* texture;
if (FAILED(resource.CopyTo(&texture)))
{
Debug::Error("Monitor::Render() => resource.As() failed.");
return;
}
D3D11_TEXTURE2D_DESC srcDesc, dstDesc;
texture->GetDesc(&srcDesc);
unityTexture_->GetDesc(&dstDesc);
if (srcDesc.Width != dstDesc.Width ||
srcDesc.Height != dstDesc.Height)
{
Debug::Error("Monitor::Render() => Texture sizes are defferent.");
Debug::Error(" Source : (", srcDesc.Width, ", ", srcDesc.Height, ")");
Debug::Error(" Dest : (", dstDesc.Width, ", ", dstDesc.Height, ")");
//Debug::Log(" => Try modifying width/height using reported value from DDA.");
//width_ = srcDesc.Width;
//height_ = srcDesc.Height;
state_ = MonitorState::TextureSizeInconsistent;
//SendMessageToUnity(Message::TextureSizeChanged);
}
else
{
ComPtr<ID3D11DeviceContext> context;
GetDevice()->GetImmediateContext(&context);
context->CopyResource(unityTexture_, texture);
}
}
cursor_->UpdateBuffer(frameInfo);
cursor_->UpdateTexture();
if (FAILED(deskDupl_->ReleaseFrame()))
{
Debug::Error("Monitor::Render() => ReleaseFrame() failed.");
}
duplicator_->Stop();
}
@@ -204,9 +135,21 @@ int Monitor::GetId() const
}
MonitorState Monitor::GetState() const
ComPtr<struct IDXGIAdapter> Monitor::GetAdapter()
{
return state_;
return adapter_;
}
ComPtr<struct IDXGIOutput> Monitor::GetOutput()
{
return output_;
}
DuplicatorState Monitor::GetDuplicatorState() const
{
return duplicator_->GetState();
}
@@ -222,21 +165,9 @@ ID3D11Texture2D* Monitor::GetUnityTexture() const
}
IDXGIOutputDuplication* Monitor::GetDeskDupl()
ComPtr<IDXGIOutputDuplication> Monitor::GetDeskDupl()
{
return deskDupl_;
}
const std::unique_ptr<Cursor>& Monitor::GetCursor()
{
return cursor_;
}
void Monitor::GetCursorTexture(ID3D11Texture2D* texture)
{
cursor_->GetTexture(texture);
return duplicator_->GetDuplication();
}
@@ -252,6 +183,12 @@ bool Monitor::IsPrimary() const
}
bool Monitor::HasBeenUpdated() const
{
return hasBeenUpdated_;
}
int Monitor::GetLeft() const
{
return static_cast<int>(outputDesc_.DesktopCoordinates.left);
@@ -303,4 +240,231 @@ int Monitor::GetWidth() const
int Monitor::GetHeight() const
{
return height_;
}
}
int Monitor::GetMoveRectCount() const
{
const auto& metaData = duplicator_->GetLastFrame().metaData;
return metaData.moveRectSize / sizeof(DXGI_OUTDUPL_MOVE_RECT);
}
DXGI_OUTDUPL_MOVE_RECT* Monitor::GetMoveRects() const
{
const auto& metaData = duplicator_->GetLastFrame().metaData;
return metaData.buffer.As<DXGI_OUTDUPL_MOVE_RECT>();
}
int Monitor::GetDirtyRectCount() const
{
const auto& metaData = duplicator_->GetLastFrame().metaData;
return metaData.dirtyRectSize / sizeof(RECT);
}
RECT* Monitor::GetDirtyRects() const
{
const auto& metaData = duplicator_->GetLastFrame().metaData;
return metaData.buffer.As<RECT>(metaData.moveRectSize);
}
void Monitor::UseGetPixels(bool use)
{
useGetPixels_ = use;
}
bool Monitor::UseGetPixels() const
{
return useGetPixels_;
}
void Monitor::CopyTextureFromGpuToCpu(ID3D11Texture2D* texture)
{
const auto monitorRot = static_cast<DXGI_MODE_ROTATION>(GetRotation());
const auto monitorWidth = GetWidth();
const auto monitorHeight = GetHeight();
const auto isVertical =
monitorRot == DXGI_MODE_ROTATION_ROTATE90 ||
monitorRot == DXGI_MODE_ROTATION_ROTATE270;
const auto desktopImageWidth = !isVertical ? monitorWidth : monitorHeight;
const auto desktopImageHeight = !isVertical ? monitorHeight : monitorWidth;
if (!textureForGetPixels_)
{
D3D11_TEXTURE2D_DESC desc;
desc.Width = desktopImageWidth;
desc.Height = desktopImageHeight;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_STAGING;
desc.BindFlags = 0;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
desc.MiscFlags = 0;
if (FAILED(GetDevice()->CreateTexture2D(&desc, nullptr, &textureForGetPixels_)))
{
Debug::Error("Monitor::CopyTextureFromGpuToCpu() => GetDevice()->CreateTexture2D() failed.");
return;
}
}
{
ComPtr<ID3D11DeviceContext> context;
GetDevice()->GetImmediateContext(&context);
context->CopyResource(textureForGetPixels_.Get(), texture);
}
ComPtr<IDXGISurface> surface;
if (FAILED(textureForGetPixels_.As(&surface)))
{
Debug::Error("Monitor::CopyTextureFromGpuToCpu() => texture.As() failed.");
return;
}
DXGI_MAPPED_RECT mappedSurface;
if (FAILED(surface->Map(&mappedSurface, DXGI_MAP_READ)))
{
Debug::Error("Monitor::CopyTextureFromGpuToCpu() => surface->Map() failed.");
return;
}
const UINT size = desktopImageWidth * desktopImageHeight * sizeof(UINT);
bufferForGetPixels_.ExpandIfNeeded(size);
std::memcpy(bufferForGetPixels_.Get(), mappedSurface.pBits, size);
if (FAILED(surface->Unmap()))
{
Debug::Error("Monitor::CopyTextureFromGpuToCpu() => surface->Unmap() failed.");
return;
}
}
bool Monitor::GetPixels(BYTE* output, int x, int y, int width, int height)
{
if (!UseGetPixels())
{
Debug::Error("Monitor::GetPixels() => UseGetPixels(true) must have been called when you want to use GetPixels().");
return false;
}
if (!bufferForGetPixels_)
{
Debug::Error("Monitor::GetPixels() => CopyTextureFromGpuToCpu() has not been called yet.");
return false;
}
const auto monitorRot = static_cast<DXGI_MODE_ROTATION>(GetRotation());
const auto monitorWidth = GetWidth();
const auto monitorHeight = GetHeight();
const auto isVertical =
monitorRot == DXGI_MODE_ROTATION_ROTATE90 ||
monitorRot == DXGI_MODE_ROTATION_ROTATE270;
const auto desktopImageWidth = !isVertical ? monitorWidth : monitorHeight;
const auto desktopImageHeight = !isVertical ? monitorHeight : monitorWidth;
// check area in destop coorinates.
int left, top, right, bottom;
switch (monitorRot)
{
case DXGI_MODE_ROTATION_ROTATE90:
{
left = y;
top = monitorWidth - x - width;
right = y + width;
bottom = monitorWidth - x;
break;
}
case DXGI_MODE_ROTATION_ROTATE180:
{
left = monitorWidth - x - width;
top = monitorHeight - y - height;
right = monitorWidth - x;
bottom = monitorHeight - y;
break;
}
case DXGI_MODE_ROTATION_ROTATE270:
{
left = monitorHeight - y - height;
top = x;
right = monitorHeight - y;
bottom = x + width;
break;
}
case DXGI_MODE_ROTATION_IDENTITY:
case DXGI_MODE_ROTATION_UNSPECIFIED:
default:
{
left = x;
top = y;
right = x + width;
bottom = y + height;
break;
}
}
if (left < 0 ||
top < 0 ||
right >= desktopImageWidth ||
bottom >= desktopImageHeight)
{
Debug::Error("Monitor::GetPixels() => is out of area.");
Debug::Error(
" ",
"(", left, ", ", top, ")",
" ~ (", right, ", ", bottom, ") > ",
"(", desktopImageWidth, ", ", desktopImageHeight, ")");
return false;
}
for (int row = 0; row < height; ++row)
{
for (int col = 0; col < width; ++col)
{
int inRow, inCol;
switch (monitorRot)
{
case DXGI_MODE_ROTATION_ROTATE90:
inCol = left + row;
inRow = bottom - 1 - col;
break;
case DXGI_MODE_ROTATION_ROTATE180:
inCol = right - 1 - col;
inRow = bottom - 1 - row;
break;
case DXGI_MODE_ROTATION_ROTATE270:
inCol = right - 1 - row;
inRow = top + col;
break;
case DXGI_MODE_ROTATION_IDENTITY:
case DXGI_MODE_ROTATION_UNSPECIFIED:
default:
inCol = left + col;
inRow = top + row;
break;
}
const auto inIndex = 4 * (inRow * desktopImageWidth + inCol);
const auto outRow = height - 1 - row;
const auto outCol = col;
const auto outIndex = 4 * (outRow * width + outCol);
// BGRA -> RGBA
output[outIndex + 0] = bufferForGetPixels_[inIndex + 2];
output[outIndex + 1] = bufferForGetPixels_[inIndex + 1];
output[outIndex + 2] = bufferForGetPixels_[inIndex + 0];
output[outIndex + 3] = bufferForGetPixels_[inIndex + 3];
}
}
return true;
}

View File

@@ -4,41 +4,37 @@
#include <dxgi1_2.h>
#include <wrl/client.h>
#include <memory>
#include <mutex>
#include <thread>
#include "Common.h"
class Cursor;
enum class MonitorState
{
NotSet = -1,
Available = 0,
InvalidArg = 1,
AccessDenied = 2,
Unsupported = 3,
CurrentlyNotAvailable = 4,
SessionDisconnected = 5,
AccessLost = 6,
TextureSizeInconsistent = 7,
Unknown = 999,
};
enum class DuplicatorState;
class Monitor
{
public:
using State = MonitorState;
explicit Monitor(int id);
~Monitor();
void Initialize(IDXGIOutput* output);
void Render(UINT timeout = 0);
void GetCursorTexture(ID3D11Texture2D* texture);
void Initialize(
const Microsoft::WRL::ComPtr<struct IDXGIAdapter> &adapter,
const Microsoft::WRL::ComPtr<struct IDXGIOutput> &output);
void Finalize();
void Render();
void StartCapture();
void StopCapture();
public:
int GetId() const;
State GetState() const;
Microsoft::WRL::ComPtr<struct IDXGIAdapter> GetAdapter();
Microsoft::WRL::ComPtr<struct IDXGIOutput> GetOutput();
DuplicatorState GetDuplicatorState() const;
void SetUnityTexture(ID3D11Texture2D* texture);
ID3D11Texture2D* GetUnityTexture() const;
void GetName(char* buf, int len) const;
bool IsPrimary() const;
bool HasBeenUpdated() const;
int GetLeft() const;
int GetRight() const;
int GetTop() const;
@@ -48,17 +44,35 @@ public:
int GetRotation() const;
int GetDpiX() const;
int GetDpiY() const;
IDXGIOutputDuplication* GetDeskDupl();
const std::unique_ptr<Cursor>& GetCursor();
Microsoft::WRL::ComPtr<IDXGIOutputDuplication> GetDeskDupl();
int GetMoveRectCount() const;
DXGI_OUTDUPL_MOVE_RECT* GetMoveRects() const;
int GetDirtyRectCount() const;
RECT* GetDirtyRects() const;
void UseGetPixels(bool use);
bool UseGetPixels() const;
bool GetPixels(BYTE* output, int x, int y, int width, int height);
private:
void CopyTextureFromGpuToCpu(ID3D11Texture2D* texture);
int id_ = -1;
UINT dpiX_ = -1, dpiY_ = -1;
int width_ = -1, height_ = -1;
State state_ = State::NotSet;
std::unique_ptr<Cursor> cursor_;
IDXGIOutputDuplication* deskDupl_ = nullptr;
ID3D11Texture2D* unityTexture_ = nullptr;
bool hasBeenUpdated_ = false;
bool useGetPixels_ = false;
Microsoft::WRL::ComPtr<IDXGIOutput> output_;
Microsoft::WRL::ComPtr<IDXGIAdapter> adapter_;
DXGI_OUTPUT_DESC outputDesc_;
MONITORINFOEX monitorInfo_;
};
std::shared_ptr<class Duplicator> duplicator_;
UINT lastFrameId_ = -1;
ID3D11Texture2D* unityTexture_ = nullptr;
Microsoft::WRL::ComPtr<ID3D11Texture2D> textureForGetPixels_;
Buffer<BYTE> bufferForGetPixels_;
};

View File

@@ -17,9 +17,10 @@
using namespace Microsoft::WRL;
MonitorManager::MonitorManager()
MonitorManager::MonitorManager(LUID unityAdapterLuid)
: unityAdapterLuid_(unityAdapterLuid)
{
Initialize();
}
@@ -51,7 +52,9 @@ void MonitorManager::Initialize()
for (int j = 0; (adapter->EnumOutputs(j, &output) != DXGI_ERROR_NOT_FOUND); ++j)
{
auto monitor = std::make_shared<Monitor>(id++);
monitor->Initialize(output.Get());
const auto unityAdapterLuid = GetUnityAdapterLuid();
monitor->Initialize(adapter, output);
monitor->StartCapture();
monitors_.push_back(monitor);
}
}
@@ -60,12 +63,28 @@ void MonitorManager::Initialize()
void MonitorManager::Finalize()
{
for (const auto& monitor : monitors_)
{
monitor->Finalize();
}
monitors_.clear();
}
void MonitorManager::Update()
{
if (isReinitializationRequired_)
{
Reinitialize();
isReinitializationRequired_ = false;
}
}
void MonitorManager::RequireReinitilization()
{
Debug::Log("MonitorManager::Reinitialize() was required.");
isReinitializationRequired_ = true;
}
@@ -104,7 +123,7 @@ bool MonitorManager::HasMonitorCountChanged() const
std::shared_ptr<Monitor> MonitorManager::GetMonitor(int id) const
{
if (id >= 0 && id < monitors_.size())
if (id >= 0 && id < static_cast<int>(monitors_.size()))
{
return monitors_[id];
}
@@ -112,25 +131,9 @@ std::shared_ptr<Monitor> MonitorManager::GetMonitor(int id) const
}
void MonitorManager::Update()
std::shared_ptr<Cursor> MonitorManager::GetCursor() const
{
if (isReinitializationRequired_)
{
Reinitialize();
isReinitializationRequired_ = false;
}
}
void MonitorManager::SetTimeout(int timeout)
{
timeout_ = timeout;
}
int MonitorManager::GetTimeout() const
{
return timeout_;
return cursor_;
}
@@ -165,4 +168,16 @@ int MonitorManager::GetTotalHeight() const
const auto minTop = *std::min_element(tops.begin(), tops.end());
const auto maxBottom = *std::max_element(bottoms.begin(), bottoms.end());
return maxBottom - minTop;
}
}
void MonitorManager::SetFrameRate(UINT frameRate)
{
frameRate_ = frameRate;
}
UINT MonitorManager::GetFrameRate() const
{
return frameRate_;
}

View File

@@ -13,35 +13,32 @@ class Cursor;
class MonitorManager
{
public:
explicit MonitorManager();
explicit MonitorManager(LUID unityAdapterLuid_);
~MonitorManager();
void Initialize();
void Finalize();
void Reinitialize();
void Update();
bool HasMonitorCountChanged() const;
void RequireReinitilization();
void SetCursorMonitorId(int id) { cursorMonitorId_ = id; }
int GetCursorMonitorId() const { return cursorMonitorId_; }
std::shared_ptr<Monitor> GetMonitor(int id) const;
std::shared_ptr<Cursor> GetCursor() const;
void SetFrameRate(UINT frameRate);
UINT GetFrameRate() const;
private:
void Initialize();
void Finalize();
// Setters from Unity
public:
void Update();
void SetTimeout(int timeout);
int GetTimeout() const;
// Getters from Unity
public:
int GetMonitorCount() const;
int GetTotalWidth() const;
int GetTotalHeight() const;
private:
int timeout_ = 10;
LUID unityAdapterLuid_;
UINT frameRate_ = 60;
bool enableTextureCopyFromGpuToCpu_ = false;
std::vector<std::shared_ptr<Monitor>> monitors_;
std::shared_ptr<Cursor> cursor_;
std::shared_ptr<Cursor> cursor_ = std::make_shared<Cursor>();
int cursorMonitorId_ = -1;
bool isReinitializationRequired_ = false;
};
};

View File

@@ -7,10 +7,12 @@
#include "IUnityInterface.h"
#include "IUnityGraphics.h"
#include "include/IUnityGraphicsD3D11.h"
#include "Common.h"
#include "Debug.h"
#include "Monitor.h"
#include "Duplicator.h"
#include "Cursor.h"
#include "MonitorManager.h"
@@ -21,41 +23,87 @@
IUnityInterfaces* g_unity = nullptr;
std::unique_ptr<MonitorManager> g_manager;
std::queue<Message> g_messages;
ID3D11DeviceContext* g_deviceContextForMainThread = nullptr;
extern "C"
{
UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API InitializeUDD()
UNITY_INTERFACE_EXPORT bool UNITY_INTERFACE_API IsInitialized()
{
return g_unity && g_manager;
}
UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API Initialize()
{
if (g_unity && !g_manager)
{
Debug::Initialize();
g_manager = std::make_unique<MonitorManager>();
auto device = g_unity->Get<IUnityGraphicsD3D11>()->GetDevice();
Microsoft::WRL::ComPtr<IDXGIDevice1> dxgiDevice;
if (FAILED(device->QueryInterface(IID_PPV_ARGS(&dxgiDevice))))
{
Debug::Error("Initialize() => device->QueryInterface() failed.");
return;
}
Microsoft::WRL::ComPtr<IDXGIAdapter> dxgiAdapter;
if (FAILED(dxgiDevice->GetAdapter(&dxgiAdapter)))
{
Debug::Error("Initialize() => dxgiDevice->GetAdapter() failed.");
return;
}
DXGI_ADAPTER_DESC desc;
dxgiAdapter->GetDesc(&desc);
g_manager = std::make_unique<MonitorManager>(desc.AdapterLuid);
g_manager->Initialize();
}
}
UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API FinalizeUDD()
UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API Finalize()
{
if (g_manager)
if (!g_manager) return;
g_manager->Finalize();
g_manager.reset();
std::queue<Message> empty;
g_messages.swap(empty);
Debug::Finalize();
}
void UNITY_INTERFACE_API OnGraphicsDeviceEvent(UnityGfxDeviceEventType event)
{
switch (event)
{
g_manager.reset();
std::queue<Message> empty;
g_messages.swap(empty);
Debug::Finalize();
case kUnityGfxDeviceEventInitialize:
{
Initialize();
break;
}
case kUnityGfxDeviceEventShutdown:
{
Finalize();
break;
}
}
}
UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API UnityPluginLoad(IUnityInterfaces* unityInterfaces)
{
g_unity = unityInterfaces;
InitializeUDD();
auto unityGraphics = g_unity->Get<IUnityGraphics>();
unityGraphics->RegisterDeviceEventCallback(OnGraphicsDeviceEvent);
}
UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API UnityPluginUnload()
{
FinalizeUDD();
auto unityGraphics = g_unity->Get<IUnityGraphics>();
unityGraphics->UnregisterDeviceEventCallback(OnGraphicsDeviceEvent);
g_unity = nullptr;
}
@@ -64,7 +112,7 @@ extern "C"
if (!g_manager) return;
if (auto monitor = g_manager->GetMonitor(id))
{
monitor->Render(g_manager->GetTimeout());
monitor->Render();
}
}
@@ -139,12 +187,6 @@ extern "C"
return g_manager->GetTotalHeight();
}
UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API SetTimeout(int timeout)
{
if (!g_manager) return;
g_manager->SetTimeout(timeout);
}
UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API GetId(int id)
{
if (!g_manager) return;
@@ -154,14 +196,14 @@ extern "C"
}
}
UNITY_INTERFACE_EXPORT MonitorState UNITY_INTERFACE_API GetState(int id)
UNITY_INTERFACE_EXPORT DuplicatorState UNITY_INTERFACE_API GetState(int id)
{
if (!g_manager) return MonitorState::NotSet;
if (!g_manager) return DuplicatorState::NotSet;
if (auto monitor = g_manager->GetMonitor(id))
{
return monitor->GetState();
return monitor->GetDuplicatorState();
}
return MonitorState::NotSet;
return DuplicatorState::NotSet;
}
UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API GetName(int id, char* buf, int len)
@@ -273,83 +315,52 @@ extern "C"
return -1;
}
UNITY_INTERFACE_EXPORT bool UNITY_INTERFACE_API IsCursorVisible(int id)
UNITY_INTERFACE_EXPORT bool UNITY_INTERFACE_API IsCursorVisible()
{
if (!g_manager) return false;
if (auto monitor = g_manager->GetMonitor(id))
{
return monitor->GetCursor()->IsVisible();
}
return false;
return g_manager->GetCursor()->IsVisible();
}
UNITY_INTERFACE_EXPORT int UNITY_INTERFACE_API GetCursorX(int id)
UNITY_INTERFACE_EXPORT int UNITY_INTERFACE_API GetCursorX()
{
if (!g_manager) return -1;
if (auto monitor = g_manager->GetMonitor(id))
{
return monitor->GetCursor()->GetX();
}
return -1;
return g_manager->GetCursor()->GetX();
}
UNITY_INTERFACE_EXPORT int UNITY_INTERFACE_API GetCursorY(int id)
UNITY_INTERFACE_EXPORT int UNITY_INTERFACE_API GetCursorY()
{
if (!g_manager) return -1;
if (auto monitor = g_manager->GetMonitor(id))
{
return monitor->GetCursor()->GetY();
}
return -1;
return g_manager->GetCursor()->GetY();
}
UNITY_INTERFACE_EXPORT int UNITY_INTERFACE_API GetCursorShapeWidth(int id)
UNITY_INTERFACE_EXPORT int UNITY_INTERFACE_API GetCursorShapeWidth()
{
if (!g_manager) return -1;
if (auto monitor = g_manager->GetMonitor(id))
{
return monitor->GetCursor()->GetWidth();
}
return -1;
return g_manager->GetCursor()->GetWidth();
}
UNITY_INTERFACE_EXPORT int UNITY_INTERFACE_API GetCursorShapeHeight(int id)
UNITY_INTERFACE_EXPORT int UNITY_INTERFACE_API GetCursorShapeHeight()
{
if (!g_manager) return -1;
if (auto monitor = g_manager->GetMonitor(id))
{
return monitor->GetCursor()->GetHeight();
}
return -1;
return g_manager->GetCursor()->GetHeight();
}
UNITY_INTERFACE_EXPORT int UNITY_INTERFACE_API GetCursorShapePitch(int id)
UNITY_INTERFACE_EXPORT int UNITY_INTERFACE_API GetCursorShapePitch()
{
if (!g_manager) return -1;
if (auto monitor = g_manager->GetMonitor(id))
{
return monitor->GetCursor()->GetPitch();
}
return -1;
return g_manager->GetCursor()->GetPitch();
}
UNITY_INTERFACE_EXPORT int UNITY_INTERFACE_API GetCursorShapeType(int id)
UNITY_INTERFACE_EXPORT int UNITY_INTERFACE_API GetCursorShapeType()
{
if (!g_manager) return -1;
if (auto monitor = g_manager->GetMonitor(id))
{
return monitor->GetCursor()->GetType();
}
return -1;
return g_manager->GetCursor()->GetType();
}
UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API GetCursorTexture(int id, ID3D11Texture2D* texture)
UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API GetCursorTexture(ID3D11Texture2D* texture)
{
if (!g_manager) return;
if (auto monitor = g_manager->GetMonitor(id))
{
monitor->GetCursorTexture(texture);
}
return g_manager->GetCursor()->GetTexture(texture);
}
UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API SetTexturePtr(int id, void* texture)
@@ -361,4 +372,79 @@ extern "C"
monitor->SetUnityTexture(d3d11Texture);
}
}
UNITY_INTERFACE_EXPORT int UNITY_INTERFACE_API GetMoveRectCount(int id)
{
if (!g_manager) return -1;
if (auto monitor = g_manager->GetMonitor(id))
{
return monitor->GetMoveRectCount();
}
return 0;
}
UNITY_INTERFACE_EXPORT void* UNITY_INTERFACE_API GetMoveRects(int id)
{
if (!g_manager) return nullptr;
if (auto monitor = g_manager->GetMonitor(id))
{
return monitor->GetMoveRects();
}
return nullptr;
}
UNITY_INTERFACE_EXPORT int UNITY_INTERFACE_API GetDirtyRectCount(int id)
{
if (!g_manager) return -1;
if (auto monitor = g_manager->GetMonitor(id))
{
return monitor->GetDirtyRectCount();
}
return 0;
}
UNITY_INTERFACE_EXPORT void* UNITY_INTERFACE_API GetDirtyRects(int id)
{
if (!g_manager) return nullptr;
if (auto monitor = g_manager->GetMonitor(id))
{
return monitor->GetDirtyRects();
}
return nullptr;
}
UNITY_INTERFACE_EXPORT bool UNITY_INTERFACE_API GetPixels(int id, BYTE* output, int x, int y, int width, int height)
{
if (!g_manager) return nullptr;
if (auto monitor = g_manager->GetMonitor(id))
{
return monitor->GetPixels(output, x, y, width, height);
}
return false;
}
UNITY_INTERFACE_EXPORT bool UNITY_INTERFACE_API HasBeenUpdated(int id)
{
if (!g_manager) return nullptr;
if (auto monitor = g_manager->GetMonitor(id))
{
return monitor->HasBeenUpdated();
}
return false;
}
UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API UseGetPixels(int id, bool use)
{
if (!g_manager) return;
if (auto monitor = g_manager->GetMonitor(id))
{
return monitor->UseGetPixels(use);
}
}
UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API SetFrameRate(UINT frameRate)
{
if (!g_manager) return;
g_manager->SetFrameRate(frameRate);
}
}

View File

@@ -1,18 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
@@ -21,33 +21,33 @@
<PropertyGroup Label="Globals">
<ProjectGuid>{BC5DE2F9-BDCC-4449-A017-E5642E04BB56}</ProjectGuid>
<RootNamespace>uDesktopDuplication</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
<ProjectName>uDesktopDuplication</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
@@ -56,32 +56,35 @@
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);include</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);include</IncludePath>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);include</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
</ClCompile>
</ItemDefinitionGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);include</IncludePath>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
@@ -91,43 +94,66 @@
<PostBuildEvent>
<Command>copy /Y "$(SolutionDir)$(Platform)\$(Configuration)\$(TargetFileName)" "$(SolutionDir)..\..\Assets\$(ProjectName)\Plugins\x86_64"</Command>
</PostBuildEvent>
<Link>
<ModuleDefinitionFile>
</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<PostBuildEvent>
<Command>
</Command>
<Command>copy /Y "$(SolutionDir)$(Platform)\$(Configuration)\$(TargetFileName)" "$(SolutionDir)..\..\Assets\$(ProjectName)\Plugins\x86"</Command>
</PostBuildEvent>
<Link>
<ModuleDefinitionFile>$(SolutionDir)$(ProjectName).def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<Optimization>Full</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<ModuleDefinitionFile>
</ModuleDefinitionFile>
</Link>
<PostBuildEvent>
<Command>copy /Y "$(SolutionDir)$(Platform)\$(Configuration)\$(TargetFileName)" "$(SolutionDir)..\..\Assets\$(ProjectName)\Plugins\x86_64"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Full</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<ModuleDefinitionFile>$(SolutionDir)$(ProjectName).def</ModuleDefinitionFile>
</Link>
<PostBuildEvent>
<Command>copy /Y "$(SolutionDir)$(Platform)\$(Configuration)\$(TargetFileName)" "$(SolutionDir)..\..\Assets\$(ProjectName)\Plugins\x86"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="Common.cpp" />
<ClCompile Include="Debug.cpp" />
<ClCompile Include="Device.cpp" />
<ClCompile Include="Duplicator.cpp" />
<ClCompile Include="MonitorManager.cpp" />
<ClCompile Include="Main.cpp" />
<ClCompile Include="Monitor.cpp" />
@@ -136,6 +162,8 @@
<ItemGroup>
<ClInclude Include="Common.h" />
<ClInclude Include="Debug.h" />
<ClInclude Include="Device.h" />
<ClInclude Include="Duplicator.h" />
<ClInclude Include="MonitorManager.h" />
<ClInclude Include="include\IUnityGraphics.h" />
<ClInclude Include="include\IUnityGraphicsD3D11.h" />

View File

@@ -20,6 +20,8 @@
<ClInclude Include="Common.h" />
<ClInclude Include="MonitorManager.h" />
<ClInclude Include="Debug.h" />
<ClInclude Include="Device.h" />
<ClInclude Include="Duplicator.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="Monitor.cpp" />
@@ -28,5 +30,7 @@
<ClCompile Include="MonitorManager.cpp" />
<ClCompile Include="Common.cpp" />
<ClCompile Include="Debug.cpp" />
<ClCompile Include="Device.cpp" />
<ClCompile Include="Duplicator.cpp" />
</ItemGroup>
</Project>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More