private void draw_ConsSpot(Graphics myGraphics, CHotSpot hspot, float winHeight, float winWidth, Matrix pm, float scaleX, float unitM = 1000) { PointF[] sd = { new PointF(0, 100) }; // 窗口 sd[0].X = (float)hspot.GlobalMileage; //sd[1].X = (float)ex; pm.TransformPoints(sd); if (sd[0].X <0 || sd[0].X> winWidth) // 如果道路不在绘制区域,返回 { return; } float unitPixelLength = unitM * scaleX; float PixelX = sd[0].X; RectangleF areaf; areaf = new RectangleF(PixelX - 12, 155, 24, 24); try { Image workingIcon = Image.FromFile(CGisDataSettings.gDataPath + @"Common\地标图片\work.gif"); myGraphics.DrawImage(workingIcon, areaf); } catch (Exception fe) { Console.WriteLine(); } }
void Initialize(CHotSpot oHotSpot) { _oHotSpot = oHotSpot; gameObject.name = "iGUICode_RootPanel_" + _oHotSpot.gameObject.name; transform.position = (4*_oHotSpot.transform.position + Camera.main.transform.position)/5; // Adopt the position of our hotspot (rotation stays pinned to camera) transform.parent = Camera.main.transform; transform.localRotation = Quaternion.Euler(0, 180f, 0); //###WEAK: Panel needs 180 degree rotation to show its right face toward the camera. Is it right or do we change it? (being attached to camera and all...) _oNodePanel = transform.FindChild("Panel"); _oTextMesh = transform.FindChild("Text").GetComponent<TextMesh>(); _oTextMesh.text = _oHotSpot.gameObject.name; //###*NOW: _oNodePanel.gameObject.layer = CCursor.C_Layer_HotSpot; //###CHECK Type oType = _oHotSpot.GetType(); foreach (FieldInfo oFieldInfo in oType.GetFields()) { //###IMPROVE: Enforce definition of 'super public' by placing test in CUtility? if (oFieldInfo.Attributes == FieldAttributes.Public && oFieldInfo.FieldType == typeof(float) && oFieldInfo.Name[0] >= 'A' && oFieldInfo.Name[0] <= 'Z') { // Only create sliders for public floats starting with a capital letter -> our definition of 'super public' _aSliders.Add(iGUICode_RootSliderOBS.Create_GuiSlider(this, _aSliders.Count, oFieldInfo)); } } float nHeightContent = 0.04f + _aSliders.Count * iGUICode_RootSliderOBS.C_SliderHeight; _oNodePanel.localScale = new Vector3(1, nHeightContent / C_PanelDefaultHeight, 1); _oTextMesh.transform.localPosition = new Vector3(0, -iGUICode_RootSliderOBS.C_SliderHeight/2, 0); BoxCollider oColBox = (BoxCollider)_oNodePanel.GetComponent<Collider>(); oColBox.center = new Vector3(0, -C_PanelDefaultHeight/2, 0); oColBox.size = new Vector3(C_PanelDefaultWidth, C_PanelDefaultHeight, 0); // We create the panel collider with no depth and control colliders with depth so they can 'poke through' and get their mouse events }
public CTEObject showTEObject(CHotSpot hs1, CHotSpot hs2, bool isStopping = false) { CTEObject obj = null; switch (hs1.ObjectType) { case "Project": CRailwayProject rp = (CRailwayProject)(hs1.ObjectRef); //string s = "当前位置: " + rp.ToString() + "\t\t"; //labelRoll2.Text = s; //labelRoll2.Refresh(); obj = showTEProject(rp, isStopping); break; case "Firm": CRailwayFirm rf = (CRailwayFirm)(hs1.ObjectRef); obj = showTEFirms(rf, isStopping); break; case "Cons": ConsLocation cl = (ConsLocation)(hs1.ObjectRef); obj = showTECons(cl, isStopping); break; } return(obj); }
public static iGUICode_RootPanelOBS Create_GuiPanel(CHotSpot oHotSpot) { GameObject oPanelResGO = Resources.Load("GUI-Panel/iGUICode_RootPanel") as GameObject; GameObject oNodePanelGO = GameObject.Instantiate(oPanelResGO) as GameObject; iGUICode_RootPanelOBS oGuiPanel = oNodePanelGO.GetComponent<iGUICode_RootPanelOBS>(); oGuiPanel.Initialize(oHotSpot); return oGuiPanel; }
public void OnStart() { _oHotSpot = CHotSpot.CreateHotspot(this, transform, "Pose Root", true, Vector3.zero, 2.0f); _oObj = new CObject(this, 0, typeof(EPoseRoot), "Pose Root"); _oObj.PropGroupBegin("", "", true); //###BROKEN: Need to flip load order, not 180!! _oObj.PropAdd(EPoseRoot.Flipped, "Flip Pose", 0, "", CProp.Local | CProp.AsCheckbox); //###IMPROVE: Add a separation member with key hook. A height too?? _oObj.FinishInitialization(); }
public static CGizmo CreateGizmo(CHotSpot oHotSpot, bool bMiddleClickOp) { Transform oGizmoTran = null; switch (CGame.INSTANCE._oCursor._EditMode) { case EEditMode.Select: return null; // We don't display a gizmo in select mode... case EEditMode.Move: oGizmoTran = (Transform)GameObject.Instantiate(CGame.INSTANCE._oCursor._Prefab_GizmoMove); break; case EEditMode.Rotate: oGizmoTran = (Transform)GameObject.Instantiate(CGame.INSTANCE._oCursor._Prefab_GizmoRotate); break; case EEditMode.Scale: oGizmoTran = (Transform)GameObject.Instantiate(CGame.INSTANCE._oCursor._Prefab_GizmoScale); break; } CGizmo oGizmoInPrefab = oGizmoTran.GetComponent<CGizmo>(); if (oGizmoInPrefab == null) CUtility.ThrowException("ERROR: CGizmo could not find CGizmo component in Gizmo prefab!"); oGizmoInPrefab.Initialize(oHotSpot, bMiddleClickOp); return oGizmoInPrefab; }
public override void OnDeserializeFromBlender() { base.OnDeserializeFromBlender(); _sBlenderInstancePath_CCloth = CBCloth.s_sNameClothSrc_HACK; //=== Create the skinned-portion of the cloth. It will be responsible for driving Flex particles that heavily influence their corresponding particles in fully-simulated cloth mesh === _oBSkinBaked_SkinnedPortion = (CBSkinBaked)CBSkinBaked.Create(null, _oBodyBase, "." + _sBlenderInstancePath_CCloth + ".oMeshClothSkinned", typeof(CBSkinBaked)); //###WEAK#13!!! F*****g dot!! _oBSkinBaked_SkinnedPortion.transform.SetParent(transform); _oBSkinBaked_SkinnedPortion._oSkinMeshRendNow.enabled = false; // Skinned portion invisible to the user. Only used to guide simulated portion //=== Receive the aMapPinnedParticles array Blender created to map the skinned verts to their pertinent simulated ones === List<ushort> aMapPinnedParticles = CByteArray.GetArray_USHORT("'CBody'", _oBodyBase._sBlenderInstancePath_CBodyBase + "." + _sBlenderInstancePath_CCloth + ".aMapPinnedParticles.Unity_GetBytes()"); //=== Create the simulated part of the cloth === MeshFilter oMeshFilter = GetComponent<MeshFilter>(); MeshRenderer oMeshRend = GetComponent<MeshRenderer>(); //oMeshRend.sharedMaterial = Resources.Load("Materials/BasicColors/TransWhite25") as Material; //####SOON? Get mats! ###F oMeshRend.sharedMaterial = Resources.Load("Materials/Test-2Sided") as Material; //####SOON? Get mats! ###F _oBSkinBaked_SkinnedPortion._oSkinMeshRendNow.sharedMaterial = oMeshRend.sharedMaterial; // Skinned part has same material _oMeshNow = oMeshFilter.sharedMesh; _oMeshNow.MarkDynamic(); // Docs say "Call this before assigning vertices to get better performance when continually updating mesh" //=== Create the 'cloth at startup' mesh. It won't get simulated and is used to reset simulated cloth to its startup position === _oBMeshClothAtStartup = CBMesh.Create(null, _oBodyBase, "." + _sBlenderInstancePath_CCloth + ".oMeshClothSimulated", typeof(CBMesh)); _oBMeshClothAtStartup.transform.SetParent(_oBodyBase.FindBone("chestUpper")); // Reparent this 'backup' mesh to the chest bone so it rotates and moves with the body _oBMeshClothAtStartup.GetComponent<MeshRenderer>().enabled = false; //_oBMeshClothAtStartup.gameObject.SetActive(false); // De activate it so it takes no cycle. It merely exists for backup purposes //=== Create the Flex object for our simulated part === CFlex.CreateFlexObject(gameObject, _oMeshNow, _oMeshNow, uFlex.FlexBodyType.Cloth, uFlex.FlexInteractionType.None, CGame.INSTANCE.nMassCloth, Color.yellow); uFlex.FlexProcessor oFlexProc = CUtility.FindOrCreateComponent(gameObject, typeof(uFlex.FlexProcessor)) as uFlex.FlexProcessor; oFlexProc._oFlexProcessor = this; _oFlexParticles = GetComponent<uFlex.FlexParticles>(); _oFlexSprings = GetComponent<uFlex.FlexSprings>(); //=== Create the managing object and related hotspot === _oObj = new CObject(this, 0, typeof(EFlexCloth), "Cloth " + gameObject.name); //###IMPROVE: Name of soft body to GUI _oObj.PropGroupBegin("", "", true); _oObj.PropAdd(EFlexCloth.Tightness, "Tightness", 1.0f, 0.01f, 2.5f, ""); _oObj.PropAdd(EFlexCloth.Length, "Length", 1.0f, 0.50f, 1.10f, ""); _oObj.PropAdd(EFlexCloth.ClothMass, "Mass", 1.0f, 0.0001f, 1000.0f, ""); _oObj.FinishInitialization(); _oWatchBone = _oBodyBase.FindBone("chestUpper"); //####HACK ####DESIGN: Assumes this cloth is a top! _oHotSpot = CHotSpot.CreateHotspot(this, _oWatchBone, "Clothing", false, new Vector3(0, 0.22f, 0.04f)); //###IMPROVE!!! Position offset that makes sense for that piece of clothing (from center of its verts?) //=== Backup the startup cloth arrays so we can adjust in a non-destructive way === _aSpringRestLengthsBAK = new float[_oFlexSprings.m_springsCount]; System.Array.Copy(_oFlexSprings.m_springRestLengths, _aSpringRestLengthsBAK, _oFlexSprings.m_springsCount); //=== Create the Flex-to-skinned-mesh component responsible to guide selected Flex particles to skinned-mesh positions === _oPinnedParticles = CUtility.FindOrCreateComponent(gameObject, typeof(CPinnedParticles)) as CPinnedParticles; _oPinnedParticles.Initialize(ref aMapPinnedParticles, _oBSkinBaked_SkinnedPortion); }
//--------------------------------------------------------------------------- UPDATE public void OnUpdate_Cursor() { // Called in CGame.update() to update our cursor //=== Switch edit mode if the corresponding key was pressed === //###DESIGN!!!!! How / when to map these important keys??? ###TODO!!!! Only change mode when in pose edit mode, enforce 'play mode' to always move! if (CGame.INSTANCE._bGameModeBasicInteractions == false) { if (Input.GetKeyDown(KeyCode.T)) { // Toggle between move and rotate mode when not in basic game interaction mode if (_EditMode == EEditMode.Move) SetEditMode(EEditMode.Rotate); else SetEditMode(EEditMode.Move); } } //=== Determine which layer we search for hotspot on === int nLayerTarget = C_Layer_HotSpot; //###BUG??? Send this layer mask to derived classes??? //if (Input.GetKey(KeyCode.Space)) //###CHECK: Proper? Hunt for hotspots on hand layer if proper key pressed // nLayerTarget = C_Layer_HotSpotHands; uint nLayerTargetMask = (uint)1 << nLayerTarget; //###WEAK? The changes above to cursor mode operation are specific to the game and take away some of the generic behavior that may be useful for other purposes if (Input.GetKeyDown(KeyCode.W)) SetEditMode(EEditMode.Move); // W = Move else if (Input.GetKeyDown(KeyCode.T)) SetEditMode(EEditMode.Rotate); // T = roTate //###WEAK: Conflicts with reset! Which to keep?? //else if (Input.GetKeyDown(KeyCode.E)) SetEditMode(EEditMode.Scale); // E = Expand = Scale //###DESIGN: Any value in scale / select for game?? //else if (Input.GetKeyDown(KeyCode.Q)) SetEditMode(EEditMode.Select); // Q = Select //=== Test what collider is under the mouse cursor. This is used to process the various stages of mouse interactivity as well as to adjust the '3D depth' of the cursor === CGame.SetGuiMessage(EGameGuiMsg.CursorStat1, "Cursor Mode: " + _eModeCursor.ToString()); _oRayHit_LayerHotSpot = GetHitOnLayerAtMousePos(0xFFFFFFFF); if (_oRayHit_LayerHotSpot.collider != null) CGame.SetGuiMessage(EGameGuiMsg.CursorStat2, "Cursor Collider: " + _oRayHit_LayerHotSpot.transform.name); else CGame.SetGuiMessage(EGameGuiMsg.CursorStat2, "Cursor Collider: None"); _oRayHit_LayerHotSpot = GetHitOnLayerAtMousePos(nLayerTargetMask); if (_oRayHit_LayerHotSpot.collider != null) _nDepth = _oRayHit_LayerHotSpot.distance * _DefaultCursorDepthOnHotspots; // We adjust the '3D depth' of mouse cursor only when a collider is found. ###IMPROVE: Implement slerp to gracefully change depth? // GameObject oSelectedUI = EventSystem.current.currentSelectedGameObject; // EventSystem.current.IsPointerOverGameObject()) { // If cursor is over Unity UI widget set cursor directly there and don't process further cursor functionality // if (oSelectedUI != null) { // CGame.SetGuiMessage(EGameGuiMsg.CursorStat3, "Cursor GUI: " + oSelectedUI.name); // //transform.position = Camera.main.ScreenToWorldPoint(; // //PointerEventData eventDataCurrentPosition = new PointerEventData(EventSystem.current); // //eventDataCurrentPosition.position = screenPosition; // //GraphicRaycaster uiRaycaster = canvas.gameObject.GetComponent<GraphicRaycaster>(); // //List<RaycastResult> results = new List<RaycastResult>(); // //uiRaycaster.Raycast(eventDataCurrentPosition, results); // //return results.Count > 0; // _nDepth = Vector3.Distance(oSelectedUI.transform.position, Camera.main.transform.position); //} else { // CGame.SetGuiMessage(EGameGuiMsg.CursorStat3, "(Cursor: No GUI control)"); // } if (_oCurrentGuiObject_HACK != null) //###CHECK: Proper transforms for VR?? For SpaceNavigator?? _nDepth = Vector3.Distance(_oCurrentGuiObject_HACK.position, Camera.main.transform.position); //###DESIGN: Override hotspot depth above?? ###IDEA: Have cursor a child of panel when it is hovering on top?? Vector3 vecMouse2D = new Vector3(Input.mousePosition.x, Input.mousePosition.y, _nDepth); //###OPT: Cache localPosition?? Vector3 vecMouse3D = Camera.main.ScreenToWorldPoint(vecMouse2D); transform.position = vecMouse3D; if (_oCurrentGuiObject_HACK != null) return; //####SOON ####PROBLEM: Detecting what widget for width (solution offered in post) bool bClickLeftDown = Input.GetMouseButtonDown(0); bool bClickRightDown = Input.GetMouseButtonDown(1); bool bClickMiddleDown = Input.GetMouseButtonDown(2); bool bClickDown = bClickLeftDown || bClickRightDown || bClickMiddleDown; //=== Process the finite state machine that systematically walks through each step of hotspot search, hovering, activation with bridge to hotspot's OnUpdate_HotSpot() for further 'OnUpdate()' processing === switch (_eModeCursor) { case EModeCursor.S1_SearchingForHotspot: // Default/startup mode: We don't have an interactive selected and are looking for one through 'mouse hover' if (_oRayHit_LayerHotSpot.collider != null) { _oHotSpotCurrent = _oRayHit_LayerHotSpot.collider.GetComponent<CHotSpot>(); if (_oHotSpotCurrent) { _oHotSpotCurrent.OnHoverBegin(); _eModeCursor = EModeCursor.S2_HoveringOverHotspot; } } else { //if (iGUICode_Root.INSTANCE._oPaneContextMenu != null) { // We kill panel when we're not hovering over any Gui collider and panel exists. (makes it have a very short lifespan exactly like a 'tooltip') // iGUICode_Root.INSTANCE._oPaneContextMenu.removeAll(); // iGUICode_Root.INSTANCE._oPaneContextMenu.setEnabled(false); //###IMPROVE!!! Implement 'tooltip-like' functionality for popup menu? // iGUICode_Root.INSTANCE._oPaneContextMenu = null; //} } break; case EModeCursor.S2_HoveringOverHotspot: // The user is now hovering over a valid Hotspot, but has not yet selected it with left mouse button. (3D cursor displays name of Hotspot for visual feedback) if (bClickDown) { if (CGame.INSTANCE._bGameModeBasicInteractions == false || bClickRightDown) { // If we're in full edit mode we wait for up-click, activate and display full gizmo. _eModeCursor = EModeCursor.S3_WaitingForMouseUp; } else { // If we're in reduced edit mode, we fast-track to immediate movement along Y,Z axis without showing gizmo _oHotSpotCurrent.OnActivate(bClickLeftDown, bClickRightDown, bClickMiddleDown); _eModeCursor = EModeCursor.S4_ActivatedHotspot; } _nTimeAtMouseButtonDown = Time.time; // Remember the start time of mouse button down to prevent acting on very long mouse clicks _vecPosAtMouseButtonDown = Input.mousePosition; // Remember mouse position so we can cancel if too far on mouse up } else { // No click on hovering hotspot, check to see if we're still on a hotspot and cancel if not. CHotSpot oHotSpot = _oRayHit_LayerHotSpot.collider ? _oRayHit_LayerHotSpot.collider.GetComponent<CHotSpot>() : null; if (oHotSpot != _oHotSpotCurrent) { _oHotSpotCurrent.OnHoverEnd(); _oHotSpotCurrent = null; _eModeCursor = EModeCursor.S1_SearchingForHotspot; } } break; case EModeCursor.S3_WaitingForMouseUp: // The user has down-clicked a hotspot. We await up-click to see if same hotspot is still under the mouse before activating the hotspot bool bClickLeftUp = Input.GetMouseButtonUp(0); bool bClickRightUp = Input.GetMouseButtonUp(1); bool bClickMiddleUp = Input.GetMouseButtonUp(2); if (bClickLeftUp|| bClickRightUp) { if (_nTimeAtMouseButtonDown + C_TimeMaxForMouseClick >= Time.time && (Input.mousePosition - _vecPosAtMouseButtonDown).magnitude < 10) { CHotSpot oHotSpot = _oRayHit_LayerHotSpot.collider ? _oRayHit_LayerHotSpot.collider.GetComponent<CHotSpot>() : null; if (oHotSpot == _oHotSpotCurrent) { // User has released mouse button on the same hotspot as mouse down. Activate the hotspot _oHotSpotCurrent.OnActivate(bClickLeftUp, bClickRightUp, bClickMiddleUp); _eModeCursor = EModeCursor.S4_ActivatedHotspot; } else { // User has released button on nothing or on another hotspot. Return to start state _oHotSpotCurrent.OnHoverEnd(); _oHotSpotCurrent = null; _eModeCursor = EModeCursor.S1_SearchingForHotspot; } } else { // User took too long, just ignore both mouse down & mouse up and return to search state _eModeCursor = EModeCursor.S1_SearchingForHotspot; } } break; case EModeCursor.S4_ActivatedHotspot: // The user is now hovering over a valid Hotspot, but has not yet selected it with left mouse button. (3D cursor displays name of Hotspot for visual feedback) if (bClickDown) { RaycastHit oRayHit_LayerHotSpotAndGizmo = GetHitOnLayerAtMousePos(nLayerTargetMask | CCursor.C_LayerMask_Gizmo); // Test to see if user clicked on nothing in gizmo or hotspot layers (in 'void') if (oRayHit_LayerHotSpotAndGizmo.collider == null) { // If user didn't click on anything we cancel hotspot activation and return to start state. _oHotSpotCurrent.OnDeactivate(); _oHotSpotCurrent.OnHoverEnd(); _oHotSpotCurrent = null; _eModeCursor = EModeCursor.S1_SearchingForHotspot; //} else { // We hit a valid hotspot or gizmo collider... //###BROKEN! Was creating multiple gizmos! // CHotSpot oHotSpot = _oRayHit_LayerHotSpot.collider ? _oRayHit_LayerHotSpot.collider.GetComponent<CHotSpot>() : null; // if (oHotSpot != null) { // if (oHotSpot == _oHotSpotCurrent) { // If user clicked same hotspot simply route the 'activate' call to it so it can display menu or start editing // _oHotSpotCurrent.OnActivate(bClickLeftDown, bClickRightDown); //###IMPROVE: Test and add quick activation?? // //} else { // If user clicked another hotspot we deactivate the old one and activate the new // // _oHotSpotCurrent.OnDeactivate(); // // _oHotSpotCurrent.OnHoverEnd(); // // _oHotSpotCurrent = oHotSpot; // // _oHotSpotCurrent.OnHoverBegin(); // // _oHotSpotCurrent.OnActivate(bClickLeftDown, bClickRightDown); //###CHECK! // } // } // In this if clause is also the possibility of a left/right click on a gizmo collider. This is handled below by hotspot } } if (_oHotSpotCurrent != null) { // Only the active hotspot gets the chance to trap events (typically to reroute to the gizmo it manages) === _oHotSpotCurrent.OnUpdate_ActiveHotspot(); //=== Handle special case if we're not showing helper object and the left or middle mouse button is not pressed -> destroy everything and returning to start state to complete the highly transient operation if (CGame.INSTANCE._bGameModeBasicInteractions && Input.GetMouseButton(0) == false && Input.GetMouseButton(2) == false) { _oHotSpotCurrent.OnDeactivate(); _oHotSpotCurrent.OnHoverEnd(); _oHotSpotCurrent = null; _eModeCursor = EModeCursor.S1_SearchingForHotspot; } } break; } }
public void CancelEditing() { // Cancels editing by deactivating hots pot which will destroy gizmo if it exists. if (_oHotSpotCurrent) { _oHotSpotCurrent.OnDeactivate(); _oHotSpotCurrent.OnHoverEnd(); } _oHotSpotCurrent = null; _eModeCursor = EModeCursor.S1_SearchingForHotspot; }
//--------------------------------------------------------------------------- INIT public override void OnDeserializeFromBlender() { base.OnDeserializeFromBlender(); transform.SetParent(_oBodyBase._oBody._oBodySkinnedMeshGO_HACK.transform); // Parent to our body's main skinned mesh ###WEAK#14: Crappy circumvent way of obtaining node we need early in init! _sNameSoftBody = GetType().Name.Substring(1); // Obtain the name of our detached body part ('Breasts', 'Penis', 'V****a') from a substring of our class name. Must match Blender!! ###WEAK? _sBlenderInstancePath_CSoftBody = ".oBody.aSoftBodies['" + _sNameSoftBody + "']"; // Simplify access to Blender CSoftBody instance _sBlenderInstancePath_CSoftBody_FullyQualfied = _oBodyBase._sBlenderInstancePath_CBodyBase + _sBlenderInstancePath_CSoftBody; // Simplify access to fully-qualified Blender CSoftBody instance (from CBody instance) _oBoneAnchor = _oBodyBase._oBody._oBodyBase.FindBone(_sNameBoneAnchor_HACK); //=== Set bounds to infinite so our dynamically-created mesh never has to recalculate bounds === _oMeshNow.bounds = CGame._oBoundsInfinite; //####IMPROVE: This can hurt performance ####OPT!! _oMeshNow.MarkDynamic(); // Docs say "Call this before assigning vertices to get better performance when continually updating mesh" //=== Create the managing object and related hotspot === _oObj = new CObject(this, 0, typeof(EFlexSoftBody), "SoftBody " + gameObject.name); //###IMPROVE: Name of soft body to GUI _oObj.PropGroupBegin("", "", true); _oObj.PropAdd(EFlexSoftBody.Volume, "Volume", 1.0f, 0.6f, 1.6f, ""); _oObj.PropAdd(EFlexSoftBody.Stiffness, "Stiffness", 1.0f, 0.001f, 1.0f, ""); //###IMPROVE: Log scale! _oObj.PropAdd(EFlexSoftBody.SoftBodyMass, "Mass", 1.0f, 0.0001f, 1000.0f, ""); _oObj.FinishInitialization(); if (GetType() != typeof(CBreastR)) //###HACK!: Right breast doesn't get hotspot (left breast gets it and manually broadcasts to right one) _oHotSpot = CHotSpot.CreateHotspot(this, _oBoneAnchor, "SoftBody", false, new Vector3(0, 0.10f, 0.08f)); //###IMPROVE!!! Position offset that makes sense for that piece of clothing (from center of its verts?) }
public void Start() { // StartCoroutine(Coroutine_StartGame()); // Handled by a coroutine so that our 'OnGui' can run to update the 'Please wait' dialog //} //public IEnumerator Coroutine_StartGame() { //####OBS: IEnumerator?? //###NOTE: Game is started by iGUICode_Root once it has completely initialized (so as to present the 'Please Wait...' dialog Debug.Log("=== CGame.StartGame() ==="); INSTANCE = this; _nTimeAtStart = Time.time; //GameObject oGO_HACK = new GameObject("oGO_HACK", typeof(CSoftBody)); //###NOW### ////GameObject oGO_HACK = new GameObject("oGO_HACK", typeof(CSoftBodyBase)); //###NOW### ////GameObject oGO_HACK = new GameObject("oGO_HACK", typeof(CB)); //###NOW### ////GameObject oGO_HACK = new GameObject("oGO_HACK", typeof(CFuckOff)); ////GameObject oGO_HACK = new GameObject("oGO_HACK", typeof(CJointDriver)); //return; _oFlexSolver = FindObjectOfType<uFlex.FlexSolver>(); //###F GameObject oSceneGO = GameObject.Find("SCENE/SceneColliders"); //if (oSceneGO != null) // s_aColliders_Scene = oSceneGO.GetComponentsInChildren<CCollider_OBS>(); _bRunningInEditor = true; //###HACK ####REVA Application.isEditor _DemoVersion = (_bRunningInEditor == false); //###CHECK? If dev has Unity code they are non-demo _oCursor = CCursor.Cursor_Create(); //###DESIGN!!!!!: REVISIT! ###CLEANUP!!!!! Cursor.visible = Application.isEditor; // _bRunningInEditor; //=== Set rapid-access members to text widgets so we can rapidly update them === _oTextUL = GameObject.Find("/UI/CanvasScreen/UL/Text-UL").GetComponent<Text>(); _oTextUC = GameObject.Find("/UI/CanvasScreen/UC/Text-UC").GetComponent<Text>(); _oTextUR = GameObject.Find("/UI/CanvasScreen/UR/Text-UR").GetComponent<Text>(); //=== Create user-adjustable top-level game options === _oObj = new CObject(this, 0, typeof(EGamePlay), "Erotic9"); //###TEMP!!! Main game name in this low-importance GUI??? _oObj.PropGroupBegin("", "", true); //###CLEANUP //_oObj.PropAdd(EGamePlay.Pleasure, "Pleasure", 30, -100, 100, "Amount of pleasure experienced by game characters. Influences 'Arousal' (NOTE: Temporary game mechanism)"); //###BUG with first setting //_oObj.PropAdd(EGamePlay.Arousal, "Arousal", 0, 0, 100, "Current state of arousal from game characters. Currently influence penis size. (NOTE: Temporary game mechanism)"); //_oObj.PropAdd(EGamePlay.PoseRootPos, "Pose Root Position",typeof(EPoseRootPos), 0, "Base location of pose root. (e.g. on bed, by bedside, etc)"); //_oObj.PropAdd(EGamePlay.PenisSize, "Penis Size", 0, 0, 100, "", CProp.ReadOnly | CProp.Hide); //_oObj.PropAdd(EGamePlay.PenisErectionMax, "Erection", 0, 0, 100, "", CProp.ReadOnly | CProp.Hide); //_oObj.PropAdd(EGamePlay.FluidConfig, "Fluid Configuration", 0, "Display the properties of the Erotic9 fluid simulator. (Advanced)", CProp.AsButton); _oObj.FinishInitialization(); _oHotSpot = CHotSpot.CreateHotspot(this, transform, "Game Options", false, new Vector3(0, 0.0f, 0.0f), 1.0f); //if (_GameModeAtStartup == EGameModes.None) { // yield break; //} float nDelayForGuiCatchup = _bRunningInEditor ? 0.2f : 0.01f; //###HACK? ###TUNE: Adjustable delay to give iGUI time to update 'Game is Loading' message, with some extra time inserted to make Unity editor appear more responsive during game awake time ///yield return new WaitForSeconds(nDelayForGuiCatchup); //=== Send async call to authentication so it is ready by the time game has initialized === // WWW oWWW = null; // if (Application.genuine) { //###CHECK: Has any value against piracy??? // if (Application.internetReachability != NetworkReachability.NotReachable) { //###CHECK!!! // //####BROKEN?! Why store it if we don't use it? string sMachineID = PlayerPrefs.GetString(G.C_PlayerPref_MachineID); // string sMachineID = CGame.GetMachineID(); //###CHECK Can cause problems if switching adaptors frequently? // oWWW = new WWW("http://www.erotic9.net/cgi-bin/CheckUser.py?Action=Authenticate&MachineID=" + sMachineID); // } else { // Debug.LogError("Warning: Could not authenticate because of Internet unreacheability."); // } // } else { // Debug.LogError("Warning: Could not authenticate because of executable image corruption."); // } //=== Try to load our dll to extract helpful error message if it fails, then release it === //Debug.Log("INIT: Attempting to load ErosEngine.dll"); //###BROKEN! WTF No longer works loading 64 bit dll?? //int hLoadLibResult = LoadLibraryEx("ErosEngine.dll", 0, 2); //if (hLoadLibResult > 32) // FreeLibrary(hLoadLibResult); // Free our dll so Unity can load it its way. Based on code sample at http://support.microsoft.com/kb/142814 //else // CUtility.ThrowException("ERROR: Failure to load ErosEngine.dll. Error code = " + hLoadLibResult); // App unusable. Study return code to find out what is wrong. //Debug.Log("INIT: Succeeded in loading ErosEngine.dll"); //####OBS? GameObject oGuiGO = GameObject.Find("iGUI"); //###TODO!!! Update game load status... ###IMPROVE: Async load so OnGUI gets called??? (Big hassle for that!) Debug.Log("0. Game Awake"); ///yield return new WaitForSeconds(nDelayForGuiCatchup); int n123 = ErosEngine.Utility_Test_Return123_HACK(); // Dummy call just to see if DLL will load with Unity if (n123 != 123) CUtility.ThrowException("ERROR: Failure to get 123 from ErosEngine.dll call to Utility_Test_Return123_HACK."); Debug.Log("INIT: Succeeded in loading ErosEngine.dll"); //=== Initialize our gBlender direct-memory buffers === Debug.Log("1. Shared Memory Creation."); //###??? new WaitForSeconds(nDelayForGuiCatchup); if (ErosEngine.gBL_Init(CGame.GetFolderPathRuntime()) == false) CUtility.ThrowException("ERROR: Could not start gBlender library! Game unusable."); //=== Spawn Blender process === Debug.Log("2. Background Server Start."); //###??? new WaitForSeconds(nDelayForGuiCatchup); //###CHECK: Cannot wait long!! _hWnd_Unity = (IntPtr)GetActiveWindow(); // Just before we start Blender obtain the HWND of our Unity editor / player window. We will need this to re-activate our window. (Starting blender causes it to activate and would require user to alt-tab back to game!!) _oProcessBlender = CGame.LaunchProcessBlender("Erotic9.blend"); if (_oProcessBlender == null) CUtility.ThrowException("ERROR: Could not start Blender! Game unusable."); //_nWnd_Blender_HACK = (IntPtr)GetActiveWindow(); //=== Start Blender (and our gBlender scripts). Game cannot run without them === Debug.Log("3. Client / Server Handshake."); //###??? new WaitForSeconds(nDelayForGuiCatchup); if (ErosEngine.gBL_HandshakeBlender() == false) CUtility.ThrowException("ERROR: Could not handshake with Blender! Game unusable."); SetForegroundWindow(_hWnd_Unity); // Set our editor / player back into focus (away from just-spawned Blender) //=== Set Blender global variables === CGame.gBL_SendCmd("G", "CGlobals.SetFlexParticleSpacing(" + CGame.INSTANCE.particleSpacing.ToString() + ")"); //###TODO: Add others? //=== Start PhysX === // Debug.Log("4. PhysX3 Init."); //###??? new WaitForSeconds(nDelayForGuiCatchup); //ErosEngine.PhysX3_Create(); // *Must* occur before any call to physics library... So make sure this object is listed with high priority in Unity's "Script Execution Order" //Debug.Log("5. PhysX2 Init."); //###??? new WaitForSeconds(nDelayForGuiCatchup); //ErosEngine.PhysX2_Create(); //###IMPROVE!!! Return argument ###NOTROBUST //Debug.Log("6. OpenCL Init."); //###??? new WaitForSeconds(nDelayForGuiCatchup); // if (System.Environment.CommandLine.Contains("-DisableOpenCL") == false) //###TODO More / better command line processing? //###SOON ####BROKEN!!!!! OpenCL breaks cloth GPU! // ErosEngine.MCube_Init(); //###IMPROVE: Log message to user! SetForegroundWindow(_hWnd_Unity); //###WEAK: Can get rid of?? //=== Start misc stuff === Debug.Log("7. CGame globals."); //###??? new WaitForSeconds(nDelayForGuiCatchup); _oSceneMeshesGO = GameObject.Find("SceneMeshes"); // Remember our scene game object so we can hide/show _aGuiMessages = new string[(int)EGameGuiMsg.COUNT]; _ShowFPS = _ShowSysInfo = _bRunningInEditor; //###IMPROVE: Disabled until we need to save CPU cycles... Create upon user demand to record script! //_oScriptRecordUserActions = new CScriptRecord(GetPathScript("RecordedScript"), "Automatically-generated Erotic9 Scene Interation Script"); _oPoseRoot = GameObject.Find("CPoseRoot").GetComponent<CPoseRoot>(); _oPoseRoot.OnStart(); //_oFluid = gameObject.AddComponent<CFluid>(); //_oFluid.OnAwake(); Application.targetFrameRate = _TargetFrameRate; //###BUG!!! Why no effect???? _DefaultJointSpringOld = _DefaultJointSpring; //###OBS _DefaultJointDampingOld = _DefaultJointDamping; _oCamTarget = GameObject.Find("CCamTarget").GetComponent<CCamTarget>(); //###WEAK!!! _oCamTarget.OnStart(); Debug.Log("8. Body Assembly."); //###??? new WaitForSeconds(nDelayForGuiCatchup); //###WEAK!!! //_oFluid.OnStart(); //###CHECK: Keep interleave SetGameModeBasicInteractions(true); //=== Find the static scene colliders in 'SceneColliders' node and initialize them === //Debug.Log("CGame.StartGame() Registering Static Colliders: " + s_aColliders_Scene.Length); // if (s_aColliders_Scene != null) //foreach (CCollider_OBS oColStatic in s_aColliders_Scene) // Colliders that are marked as static registered themselves to us in their Awake() so we can start and destroy them // oColStatic.OnStart(); //StartCoroutine(Coroutine_Update100ms()); StartCoroutine(Coroutine_Update500ms()); _GameIsRunning = true; enabled = true; Debug.Log("+++ GameIsRunning ++"); Debug.Log("7. Scene settling time."); //###??? new WaitForSeconds(2.0f); //###DESIGN?? ###TUNE?? ///_oGui.ShowSceneBlanker(false); ///_oGui.ShowPanelGameLoad(false); //=== Check result of user authentication === /* if (oWWW != null) { yield return oWWW; string sResultAuth = oWWW.text; _DemoVersion = sResultAuth.Contains("Result=OK") == false; //###IMPROVE: Create parse routine and return server errors Debug.Log("Auth Results = " + sResultAuth); if (_DemoVersion == false) Debug.Log("Starting game in non-demo mode."); }*/ //_DemoVersion = false; //if (_DemoVersion) // Debug.Log("Starting game in demo mode."); //###TODO: Temp caption! /// if (_bRunningInEditor == false) /// CUtility.WndPopup_Create(EWndPopupType.LearnToPlay, null, "Online Help", 50, 50); // Show the help dialog at start... ###BUG: Does not change the combo box at top! SetForegroundWindow(_hWnd_Unity); //###WEAK: Can get rid of?? //if (CGame.INSTANCE._GameMode == EGameModes.None) //####TEMP // return; //=== Create the body publicly-editable body definitions that can construct and reconstruct CBody instances === //CGame.INSTANCE._nNumPenisInScene_BROKEN = 0; //###NOTE: For simplification in pose files we always have two bodies in the scene with man/shemale being body 0 and woman body 1 //CreateBody(0); // //CreateBody(1); _aBodyBases[0] = new CBodyBase(0, EBodySex.Woman); //###BROKEN _aBodyBases[0].SelectBody(); TemporarilyDisablePhysicsCollision(); ///SetPenisInVagina(false); // We initialize the penis in v****a state to false so v****a track colliders don't kick in at scene init if (CGame.INSTANCE._GameMode == EGameModes.Play) ScenePose_Load("Standing", false); // Load the default scene pose //###TODO ##NOW: Init GUI first!! //iGUISmartPrefab_WndPopup.WndPopup_Create(new CObject[] { oObj }, "Game Play", 0, 0); //###TEMP //Time.timeScale = 0.05f; //###REVA ###TEMP Gives more time for cloth to settle... but fix it some other way (with far stronger params??) ChangeGameMode(_GameModeAtStartup); // Set the initial game mode as statically requested Debug.LogFormat("Time at startup end: {0}", Time.time - _nTimeAtStart); //ScenePose_Load("Standing", false); // Load the default scene pose }
void Initialize(CHotSpot oHotSpot, bool bMiddleClickOp) { _oHotSpot = oHotSpot; _bMiddleClickOp = bMiddleClickOp; _eEditMode = CGame.INSTANCE._oCursor._EditMode; // Our gizmo mode is the mode of the cursor edit mode at startup. gameObject.name = "Gizmo-" + _eEditMode.ToString(); //=== Set the initializing gizmo the position and rotation of the hotspot. We have to move/rotate both at every frame === transform.parent = null; // Note that we are NOT a child of our owning hotspot... transform.position = _oHotSpot.transform.position; if (_eEditMode != EEditMode.Move) // Only start at the object's current location if we're rotate or scale. we always move with axis-aliged gizmo transform.rotation = _oHotSpot.transform.rotation; transform.localScale = new Vector3(CCursor.C_GizmoScale, CCursor.C_GizmoScale, CCursor.C_GizmoScale); // Gizmo is always drawn at the default scale regardless of hotspot scaling. if (_eEditMode == EEditMode.Rotate) // Magnify the rotation cursor a given ratio as it frequently needs a bigger size for easy user manipulation transform.localScale *= CCursor.C_GizmoScale_RotationMultiplier; //=== Handling of special 'hidden helper object' mode = Hide gizmo and immediately begin move opeation along y,z axis === if (CGame.INSTANCE._bGameModeBasicInteractions) { Renderer[] aRend = transform.GetComponentsInChildren<Renderer>(); //###IMPROVE? Instead of hiding all gizmo elements, would it be too tough to just not instantiate its prefab?? foreach (Renderer oRend in aRend) oRend.enabled = false; _eModeGizmo = EModeGizmo.S2_UserDraggingGizmoPart; // Direct fast-track to immediately drag gizmo... GizmoTransform_Begin(true); // ... by forcing a move operation on YZ plane } else { _eModeGizmo = EModeGizmo.S1_WaitingLeftClickGizmoPart; } }