From 6ed65dcb597fb2153cef75bf1845978f1115658c Mon Sep 17 00:00:00 2001 From: Normand Briere <nbriere@noware.ca> Date: Fri, 14 Dec 2018 22:53:55 -0500 Subject: [PATCH] Repair shadow, normal push + attractor mesh. --- ObjEditor.java | 40 ++ Texture.java | 2 NumberSlider.java | 1 Mocap.java | 156 +++++++----- BiparamEditor.java | 4 FileObject.java | 11 ScriptNode.java | 8 BoundaryRep.java | 2 CameraPane.java | 92 ++++-- cSpringEditor.java | 10 GroupEditor.java | 17 + cSpring.java | 231 +++++++++++++----- Object3D.java | 106 +++++++- 13 files changed, 469 insertions(+), 211 deletions(-) diff --git a/BiparamEditor.java b/BiparamEditor.java index 6fde80f..c04a299 100644 --- a/BiparamEditor.java +++ b/BiparamEditor.java @@ -68,7 +68,7 @@ uDivsField = AddSlider(oe.ctrlPanel, "U #", biparam.minUDivs, 250+biparam.minUDivs, biparam.uDivs); Return(); - vDivsField = AddSlider(oe.ctrlPanel, "V #", biparam.minVDivs, (int)(250/6.28)+biparam.minVDivs, biparam.vDivs); + vDivsField = AddSlider(oe.ctrlPanel, "V #", biparam.minVDivs, (int)(500/3.14)+biparam.minVDivs, biparam.vDivs); Return(); // oe.aConstraints.gridwidth = 1; // oe.aConstraints.fill = GridBagConstraints.VERTICAL; @@ -205,7 +205,7 @@ public void applySelf() { //System.out.println("Biparam :: applySelf"); - //super.applySelf(); + super.applySelf(); int udivs = uDivsField.getInteger(); // biparam.minUDivs, 99); int vdivs = vDivsField.getInteger(); // biparam.minUDivs, 99); //biparam.name = nameField.getText(); diff --git a/BoundaryRep.java b/BoundaryRep.java index 3a1d080..d786a91 100644 --- a/BoundaryRep.java +++ b/BoundaryRep.java @@ -4948,7 +4948,7 @@ { Vertex v = GetVertex(i); - if (v.norm.x == 0 && v.norm.y == 0 && v.norm.z == 0) + if (v.norm == null || v.norm.x == 0 && v.norm.y == 0 && v.norm.z == 0) continue; from.set(v.x, v.y, v.z); diff --git a/CameraPane.java b/CameraPane.java index f2d438e..a5a5ed5 100644 --- a/CameraPane.java +++ b/CameraPane.java @@ -7444,6 +7444,8 @@ //gl.glFrustum(-0.5*scale, 0.5*scale, -0.5*scale, 0.5*scale, 1, 100); //glu.gluPerspective(lightshaper_fovy, 1, lightshaper_zNear, lightshaper_zFar); double scale = lightCamera.SCALE / lightCamera.Distance(); +// PATCH FILLE AUX JEANS + //scale *= lightCamera.shaper_fovy / 25; gl.glScaled(2 * scale, 2 * scale, -scale); gl.glTranslated(0, 0, lightCamera.DECAL); @@ -9092,6 +9094,8 @@ //gl.glFrustum(-0.5*scale, 0.5*scale, -0.5*scale, 0.5*scale, 1, 100); //glu.gluPerspective(lightshaper_fovy, 1, lightshaper_zNear, lightshaper_zFar); double scale = lightCamera.SCALE / lightCamera.Distance(); +// PATCH FILLE AUX JEANS + //scale *= lightCamera.shaper_fovy / 25; gl.glScaled(2 * scale, 2 * scale, -scale); gl.glTranslated(0, 0, lightCamera.DECAL); @@ -9231,6 +9235,8 @@ { //glu.gluPerspective(lightshaper_fovy, 1, lightshaper_zNear, lightshaper_zFar); double scale = lightCamera.SCALE / lightCamera.Distance(); +// PATCH FILLE AUX JEANS + //scale *= lightCamera.shaper_fovy / 25; gl.glScaled(2 * scale, 2 * scale, -scale); gl.glTranslated(0, 0, lightCamera.DECAL); //System.out.println("DECAL = " + LIGHTDECAL + "; SCALE = " + LIGHTSCALE); @@ -9754,40 +9760,40 @@ selectedpoint.radius = radius; selectedpoint.recalculate(); selectedpoint.material = new cMaterial(); - selectedpoint.material.color = 0.15f; + selectedpoint.material.color = 0.15f; // Yellow selectedpoint.material.modulation = 0.75f; - debugpoint.radius = radius; - debugpoint.recalculate(); - debugpoint.material = new cMaterial(); - debugpoint.material.color = 0.25f; - debugpoint.material.modulation = 0.75f; + debugpointG.radius = radius; + debugpointG.recalculate(); + debugpointG.material = new cMaterial(); + debugpointG.material.color = 0.25f; // Green + debugpointG.material.modulation = 0.75f; - debugpoint2.radius = radius; - debugpoint2.recalculate(); - debugpoint2.material = new cMaterial(); - debugpoint2.material.color = 0.75f; - debugpoint2.material.modulation = 0.75f; + debugpointP.radius = radius; + debugpointP.recalculate(); + debugpointP.material = new cMaterial(); + debugpointP.material.color = 0.75f; // Purple + debugpointP.material.modulation = 0.75f; - debugpoint3.radius = radius; - debugpoint3.recalculate(); - debugpoint3.material = new cMaterial(); - debugpoint3.material.color = 0.5f; - debugpoint3.material.modulation = 0.75f; + debugpointC.radius = radius; + debugpointC.recalculate(); + debugpointC.material = new cMaterial(); + debugpointC.material.color = 0.5f; // Cyan + debugpointC.material.modulation = 0.75f; - debugpoint4.radius = radius; - debugpoint4.recalculate(); - debugpoint4.material = new cMaterial(); - debugpoint4.material.color = 0f; - debugpoint4.material.modulation = 0.75f; + debugpointR.radius = radius; + debugpointR.recalculate(); + debugpointR.material = new cMaterial(); + debugpointR.material.color = 0f; // Red + debugpointR.material.modulation = 0.75f; InitPoints(radius); } selectedpoint.draw(this, /*(Composite)*/ null, false, false); - debugpoint.draw(this, /*(Composite)*/ null, false,false); - debugpoint2.draw(this, /*(Composite)*/ null, false,false); - debugpoint3.draw(this, /*(Composite)*/ null, false,false); - debugpoint4.draw(this, /*(Composite)*/ null, false,false); + debugpointG.draw(this, /*(Composite)*/ null, false,false); + debugpointP.draw(this, /*(Composite)*/ null, false,false); + debugpointC.draw(this, /*(Composite)*/ null, false,false); + debugpointR.draw(this, /*(Composite)*/ null, false,false); // DrawPoints(this); } @@ -9825,12 +9831,14 @@ if (checker != null && drawMode == DEFAULT) { - // BindTexture(IMMORTAL_TEXTURE); + //BindTexture(IMMORTAL_TEXTURE); + BindTextures(checker.GetTextures(), checker.texres); // NEAREST GetGL().glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST); // GL.GL_LINEAR); DrawChecker(gl); //checker.Draw(this, null, false); // ReleaseTexture(IMMORTAL_TEXTURE); + ReleaseTextures(checker.GetTextures()); } if (object.parent != null) @@ -10388,6 +10396,7 @@ "PARAM lodbias = { 10,10,10,10 };" + // 20, -2, -20, 1.0 };" + "PARAM infinity = { 100000000, 100000000, 100000000, 1.0 };" + "PARAM one2048th = { 0.00048828125, 0.00048828125, 0.00048828125, 1.0 };" + + "PARAM ninetenth = { 0.9, 0.9, 0.9, 1.0 };" + "PARAM almostone = { 0.999, 0.999, 0.999, 1.0 };" + "PARAM c256 = { 256, 256, 256, 1.0 };" + "PARAM c256i = { 0.00390625, 0.00390625, 0.00390625, 1.0 };" + @@ -11302,6 +11311,7 @@ String Shadow(String depth, String shadow) { return "MAX temp.x, ndotl.x, one64th.x;" + + "MIN temp.x, temp.x, ninetenth.x;" + /**/ // Sine "MUL temp.y, temp.x, temp.x;" + @@ -14438,7 +14448,7 @@ gl.glPushAttrib(GL.GL_ALL_ATTRIB_BITS); gl.glPushMatrix(); gl.glLoadIdentity(); - PushMatrix(checker.toParent); + //PushMatrix(checker.toParent); gl.glMatrixMode(GL.GL_TEXTURE); gl.glPushMatrix(); @@ -14461,8 +14471,8 @@ gl.glNormal3f(0.0f, 0.0f, 1.0f); - float step = 0.1666f; //0.25f; - float stepv = step * 1652 / 998; + float step = 2; // 0.1666f; //0.25f; + float stepv = 2; // step * 1652 / 998; int i0 = 0; /* @@ -14532,15 +14542,27 @@ //float u = (i+1)/2; //float v = (j+1)/2; - gl.glTexCoord2f((i + 1) / 2, (j + 1) / 2); // (1,0) // (i+1+step)/2,(j+1)/2); + if (checker.flipV) + gl.glTexCoord2f((i + 1) / 2, 1 - (j + 1) / 2); + else + gl.glTexCoord2f((i + 1) / 2, (j + 1) / 2); // (1,0) // (i+1+step)/2,(j+1)/2); gl.glVertex3f(i, j, -0.5f); + if (checker.flipV) + gl.glTexCoord2f((i + 1 + step) / 2, 1 - (j + 1) / 2); // (1,1) // (i+1+step)/2,(j+1+step)/2); + else gl.glTexCoord2f((i + 1 + step) / 2, (j + 1) / 2); // (1,1) // (i+1+step)/2,(j+1+step)/2); gl.glVertex3f(i + step, j, -0.5f); + if (checker.flipV) + gl.glTexCoord2f((i + 1 + step) / 2, 1 - (j + 1 + stepv) / 2); // (0,1) //(i+1)/2,(j+1+step)/2); + else gl.glTexCoord2f((i + 1 + step) / 2, (j + 1 + stepv) / 2); // (0,1) //(i+1)/2,(j+1+step)/2); gl.glVertex3f(i + step, j + stepv, -0.5f); + if (checker.flipV) + gl.glTexCoord2f((i + 1) / 2, 1 - (j + 1 + stepv) / 2); // (0,0) //(i+1)/2,(j+1)/2); + else gl.glTexCoord2f((i + 1) / 2, (j + 1 + stepv) / 2); // (0,0) //(i+1)/2,(j+1)/2); gl.glVertex3f(i, j + stepv, -0.5f); } @@ -14552,7 +14574,7 @@ gl.glMatrixMode(GL.GL_PROJECTION); gl.glPopMatrix(); gl.glMatrixMode(GL.GL_MODELVIEW); - PopMatrix(null); // checker.toParent); // null); + //PopMatrix(null); // checker.toParent); // null); gl.glPopMatrix(); PopTextureMatrix(checker.toParent); gl.glMatrixMode(GL.GL_TEXTURE); @@ -15370,10 +15392,10 @@ //double[] selectedpoint = new double[3]; static Superellipsoid selectedpoint = new Superellipsoid(); static Sphere previousselectedpoint = null; - static Sphere debugpoint = new Sphere(); - static Sphere debugpoint2 = new Sphere(); - static Sphere debugpoint3 = new Sphere(); - static Sphere debugpoint4 = new Sphere(); + static Sphere debugpointG = new Sphere(); + static Sphere debugpointP = new Sphere(); + static Sphere debugpointC = new Sphere(); + static Sphere debugpointR = new Sphere(); static Sphere debugpoints[] = new Sphere[8]; diff --git a/FileObject.java b/FileObject.java index e41d012..6de2b2c 100644 --- a/FileObject.java +++ b/FileObject.java @@ -22,10 +22,10 @@ return false; // ???? false; } - void Reset() - { - // filecontent = null; - } +// void Reset() +// { +// // filecontent = null; +// } void ClearUI() { @@ -54,9 +54,12 @@ else { filecontent = ObjEditor.ReadGFD/*z*/(name); + if (filecontent != null) + { filecontent.parent = null; filecontent.fileparent = this; filecontent.RepairTexture(); + } // stripify on load instead? // OK... // filecontent.Stripify(); // fine. faster and read-only anyway diff --git a/GroupEditor.java b/GroupEditor.java index 48fcf23..da3ecc4 100644 --- a/GroupEditor.java +++ b/GroupEditor.java @@ -1120,6 +1120,8 @@ resetParentItem.addActionListener(this); repairParentItem = menu.add(new MenuItem("Repair Parent")); repairParentItem.addActionListener(this); + repairShadowItem = menu.add(new MenuItem("Repair Shadow")); + repairShadowItem.addActionListener(this); menu.add(invariantsItem = new MenuItem("Invariants")); invariantsItem.addActionListener(this); menu.add(recompileItem = new MenuItem("Recompile")); @@ -2537,6 +2539,20 @@ { Object3D obj = (Object3D)e.nextElement(); obj.RepairParent(); +// for (int i=0; i<obj.size(); i++) +// { +// obj.get(i).parent = obj; +// } + } + + refreshContents(); + } else + if (event.getSource() == repairShadowItem) + { + for (Enumeration e = group.selection.elements(); e.hasMoreElements();) + { + Object3D obj = (Object3D)e.nextElement(); + obj.RepairShadow(); // for (int i=0; i<obj.size(); i++) // { // obj.get(i).parent = obj; @@ -5009,6 +5025,7 @@ private MenuItem resetParentItem; private MenuItem repairParentItem; + private MenuItem repairShadowItem; private MenuItem sortbysizeItem; private MenuItem sortbynameItem; diff --git a/Mocap.java b/Mocap.java index 172ab78..f451172 100644 --- a/Mocap.java +++ b/Mocap.java @@ -261,9 +261,9 @@ // LA.matConcat(toParent, hip.get(0).toParent, toParent); - CameraPane.debugpoint.toParent[3][0] = poship.x; - CameraPane.debugpoint.toParent[3][1] = poship.y; - CameraPane.debugpoint.toParent[3][2] = poship.z; + CameraPane.debugpointG.toParent[3][0] = poship.x; + CameraPane.debugpointG.toParent[3][1] = poship.y; + CameraPane.debugpointG.toParent[3][2] = poship.z; LA.matInvert(toParent, fromParent); @@ -324,21 +324,21 @@ // LA.matYRotate(toParent, angleY - angleYhip); // LA.matTranslate(toParent, pos.x - poship.x, pos.y - poship.y, pos.z - poship.z); - CameraPane.debugpoint2.toParent[3][0] = pos.x; - CameraPane.debugpoint2.toParent[3][1] = pos.y; - CameraPane.debugpoint2.toParent[3][2] = pos.z; + CameraPane.debugpointP.toParent[3][0] = pos.x; + CameraPane.debugpointP.toParent[3][1] = pos.y; + CameraPane.debugpointP.toParent[3][2] = pos.z; - CameraPane.debugpoint3.toParent[3][0] = poship.x; - CameraPane.debugpoint3.toParent[3][1] = poship.y; - CameraPane.debugpoint3.toParent[3][2] = poship.z; + CameraPane.debugpointC.toParent[3][0] = poship.x; + CameraPane.debugpointC.toParent[3][1] = poship.y; + CameraPane.debugpointC.toParent[3][2] = poship.z; poship.x = toParent[3][0]; poship.y = toParent[3][1]; poship.z = toParent[3][2]; - CameraPane.debugpoint4.toParent[3][0] = poship.x; - CameraPane.debugpoint4.toParent[3][1] = poship.y; - CameraPane.debugpoint4.toParent[3][2] = poship.z; + CameraPane.debugpointR.toParent[3][0] = poship.x; + CameraPane.debugpointR.toParent[3][1] = poship.y; + CameraPane.debugpointR.toParent[3][2] = poship.z; LA.matInvert(toParent, fromParent); } @@ -477,29 +477,45 @@ } } + static cVector centroid = new cVector(); + static cVector mocaporigin = new cVector(); + void SetHipOrientation() { Object3D hip = get(0); LA.matConcat(toParent, hip.get(0).toParent, matrix); - cVector centroid = new cVector(); + mocaporigin.x = matrix[3][0]; + mocaporigin.y = matrix[3][1]; + mocaporigin.z = matrix[3][2]; + centroid.x = matrix[3][0]; centroid.y = matrix[3][1]; centroid.z = matrix[3][2]; - this.getCentroid(centroid, true); +// this.getCentroid(centroid, true); + + CameraPane.debugpointG.name = ""; + CameraPane.debugpointG.toParent[3][0] = mocaporigin.x; + CameraPane.debugpointG.toParent[3][1] = mocaporigin.y; + CameraPane.debugpointG.toParent[3][2] = mocaporigin.z; + + CameraPane.debugpointP.name = ""; + CameraPane.debugpointP.toParent[3][0] = centroid.x; + CameraPane.debugpointP.toParent[3][1] = centroid.y; + CameraPane.debugpointP.toParent[3][2] = centroid.z; cVector goal = GetGoal(centroid); if (goal != null) { - System.err.println("GOAL change (" + this + "): " + goal + " (was " + goalx + ", " + goalz + ")"); + System.err.println("GOAL change (" + this + "): " + goal + " (was " + goalposx + ", " + goalposz + ")"); - goalx = goal.x; - goalz = goal.z; - targetx = targetz = 0; + goalposx = goal.x; + goalposz = goal.z; + targetdirx = targetdirz = 0; } - if (goalx == 0 && goalz == 0) + if (goalposx == 0 && goalposz == 0) { // No target if (ScriptNode.speaker != null) @@ -533,8 +549,8 @@ //sourcenode.parent.TransformToLocal(dst); this.parent.TransformToLocal(dst); - goalx = dst.x; - goalz = dst.z; + goalposx = dst.x; + goalposz = dst.z; } else return; @@ -550,17 +566,25 @@ double angleYhip = Math.atan2(-temp.z, temp.x); - double angleYtarget = Math.atan2(goalx - centroid.x, goalz - centroid.z); + double angleYtarget = Math.atan2(goalposx - centroid.x, goalposz - centroid.z); LA.matIdentity(matrix); LA.matTranslate(matrix, -centroid.x, -centroid.y, -centroid.z); - double angle = CurveAngle(0, angleYtarget - angleYhip, 1); // 0.1f); + double angle = CurveAngle(0, angleYtarget - angleYhip, 0.1f); LA.matYRotate(matrix, angle); LA.matTranslate(matrix, centroid.x, centroid.y, centroid.z); LA.matConcat(matrix, toParent, toParent); LA.matInvert(toParent, fromParent); + + LA.matConcat(toParent, hip.get(0).toParent, matrix); + + centroid.x = matrix[3][0]; + centroid.y = matrix[3][1]; + centroid.z = matrix[3][2]; + + double dist = LA.distance(centroid, mocaporigin); CheckForAction(centroid); } @@ -637,11 +661,11 @@ double pinx; double pinz; - double targetx; - double targetz; + double targetdirx; + double targetdirz; - double goalx = -20; - double goalz = -10; + double goalposx = -20; + double goalposz = -10; boolean followpath; @@ -712,7 +736,7 @@ scriptactions.clear(); } - static double EPSACTION = 0.1; // 0.075; // 0.1; + static double EPSACTION = 0.1; // 0.075; // 0.1;Came void AddFromTo(cVector from, cVector to) { @@ -1278,6 +1302,7 @@ void SetPosition(Object3D sourcenode, cVector floor, long floorid, cVector centroid) { + assert(false); //assert(CameraPane.drawMode == CameraPane.SHADOW); Object3D transformnode = new Object3D(); @@ -1481,9 +1506,9 @@ groundid = floorid; // green - CameraPane.debugpoint.toParent[3][0] = groundx; - CameraPane.debugpoint.toParent[3][1] = floor.y; - CameraPane.debugpoint.toParent[3][2] = groundz; + CameraPane.debugpointG.toParent[3][0] = groundx; + CameraPane.debugpointG.toParent[3][1] = floor.y; + CameraPane.debugpointG.toParent[3][2] = groundz; if (true) // slow && stepout && onein) { @@ -1560,9 +1585,9 @@ // System.out.println("Allo " + sourcenode); // purple - CameraPane.debugpoint2.toParent[3][0] = floor.x;// + posx; - CameraPane.debugpoint2.toParent[3][1] = ground; // floor.y;// + sourcenode.parent.toParent[3][1]; - CameraPane.debugpoint2.toParent[3][2] = floor.z;// + posz; + CameraPane.debugpointP.toParent[3][0] = floor.x;// + posx; + CameraPane.debugpointP.toParent[3][1] = ground; // floor.y;// + sourcenode.parent.toParent[3][1]; + CameraPane.debugpointP.toParent[3][2] = floor.z;// + posz; if (false) // dist2 > 0.1) @@ -1628,9 +1653,9 @@ this.get(0).TransformToWorld(v0); // cyan - CameraPane.debugpoint3.toParent[3][0] = v0.x; - CameraPane.debugpoint3.toParent[3][1] = ground; - CameraPane.debugpoint3.toParent[3][2] = v0.z; + CameraPane.debugpointC.toParent[3][0] = v0.x; + CameraPane.debugpointC.toParent[3][1] = ground; + CameraPane.debugpointC.toParent[3][2] = v0.z; LA.matConcat(sourcenode.toParent, transformnode.toParent, sourcenode.toParent); LA.matInvert(sourcenode.toParent, sourcenode.fromParent); @@ -1640,9 +1665,9 @@ this.get(0).TransformToWorld(v0); // red - CameraPane.debugpoint4.toParent[3][0] = v0.x; - CameraPane.debugpoint4.toParent[3][1] = ground; - CameraPane.debugpoint4.toParent[3][2] = v0.z; + CameraPane.debugpointR.toParent[3][0] = v0.x; + CameraPane.debugpointR.toParent[3][1] = ground; + CameraPane.debugpointR.toParent[3][2] = v0.z; } } @@ -1682,11 +1707,11 @@ if (goal != null) { - System.err.println("GOAL change (" + sourcenode + "): " + goal + " (was " + goalx + ", " + goalz + ")"); + System.err.println("GOAL change (" + sourcenode + "): " + goal + " (was " + goalposx + ", " + goalposz + ")"); //sourcenode.parent.parent.Dump(); - goalx = goal.x; - goalz = goal.z; - targetx = targetz = 0; + goalposx = goal.x; + goalposz = goal.z; + targetdirx = targetdirz = 0; followpath = true; } @@ -1737,16 +1762,16 @@ // } if (false) // !uselast) { - CameraPane.debugpoint.toParent[3][0] = dst.x; - CameraPane.debugpoint.toParent[3][1] = dst.y; - CameraPane.debugpoint.toParent[3][2] = dst.z; + CameraPane.debugpointG.toParent[3][0] = dst.x; + CameraPane.debugpointG.toParent[3][1] = dst.y; + CameraPane.debugpointG.toParent[3][2] = dst.z; } } - if (goalx != 0 || goalz != 0) // TODO + if (goalposx != 0 || goalposz != 0) // TODO { // overwrite speaker orientation - dst.set(goalx,0,goalz); + dst.set(goalposx,0,goalposz); if (sourcenode.parent != null) // july 2014 sourcenode.parent. TransformToLocal(dst); @@ -1798,26 +1823,26 @@ // mars 2014 if (false) // goalx != 0 || goalz != 0) { - targetx = dst.x - src.x; - targetz = dst.z - src.z; + targetdirx = dst.x - src.x; + targetdirz = dst.z - src.z; - if (Math.abs(targetx) > 0.1 || Math.abs(targetz) > 0.1) + if (Math.abs(targetdirx) > 0.1 || Math.abs(targetdirz) > 0.1) { // far enough from goal. keep the goal position. - targetx = 0; - targetz = 0; + targetdirx = 0; + targetdirz = 0; } else { // too close to goal. switch to target direction instead. - goalx = 0; - goalz = 0; + goalposx = 0; + goalposz = 0; } } //sourcenode.getCentroid(src, true); - if (speakernode == sourcenode && goalx == 0 && goalz == 0) + if (speakernode == sourcenode && goalposx == 0 && goalposz == 0) { if (ScriptNode.lastspeaker != null) new Exception().printStackTrace(); @@ -1826,13 +1851,13 @@ // LA.xformPos(src, fromParent, src); - if ((ScriptNode.speaker != null && CameraPane.SPEAKERMOCAP || goalx != 0 || goalz != 0) && targetx == 0 && targetz == 0) + if ((ScriptNode.speaker != null && CameraPane.SPEAKERMOCAP || goalposx != 0 || goalposz != 0) && targetdirx == 0 && targetdirz == 0) dst.sub(src); else // vector mode { - dst.x = targetx; - dst.z = targetz; + dst.x = targetdirx; + dst.z = targetdirz; // TEST TARGET // dst.x = CameraPane.selectedpoint.toParent[3][0]; @@ -2280,9 +2305,16 @@ toVector.x = LA.cos(to); toVector.y = LA.sin(to); + double fromA = Math.atan2(fromVector.y, fromVector.x); + double toA = Math.atan2(toVector.y, toVector.x); + Vector2d currentVector = Slerp(fromVector, toVector, step); - return Math.atan2(currentVector.y, currentVector.x); + double angle = Math.atan2(currentVector.y, currentVector.x); + + double angle2 = (1-step) * fromA + step * toA; + + return angle; } public static Vector2d Slerp(Vector2d from, Vector2d to, double step) @@ -3191,7 +3223,7 @@ // july 2014 // goalx = goalz = 0; - targetx = targetz = 0; + targetdirx = targetdirz = 0; //SetPositionDelta(true, true, true, false); // LoadData(); diff --git a/NumberSlider.java b/NumberSlider.java index 25db748..5c7135a 100644 --- a/NumberSlider.java +++ b/NumberSlider.java @@ -102,6 +102,7 @@ if (pow <= 0) { + // Transition between min and max // value = (Math.pow(getValue()/1000.0, POW) * (max - min)) + min; // value - min = Math.pow(getValue()/1000.0, POW) * (max - min); // (value - min) / (max - min) = Math.pow(getValue()/1000.0, POW); diff --git a/ObjEditor.java b/ObjEditor.java index a0dc1a7..f7c8293 100644 --- a/ObjEditor.java +++ b/ObjEditor.java @@ -160,12 +160,16 @@ objEditor.ctrlPanel.remove(slowerButton); objEditor.ctrlPanel.remove(fasterButton); objEditor.ctrlPanel.remove(remarkButton); + + Remove(normalpushField); } public ObjEditor GetEditor() { return objEditor; //.GetEditor(); } + + // Sometimes myself, sometimes my callee's. ObjEditor objEditor; /* @@ -814,7 +818,7 @@ aConstraints.fill = GridBagConstraints.VERTICAL; jlabel.setHorizontalAlignment(SwingConstants.TRAILING); - aConstraints.gridwidth = 2; + aConstraints.gridwidth = 1; ctrlPanel.add(jlabel, aConstraints); //, oe.ctrlPanel.getComponentCount()-1); aConstraints.gridx += 1; aConstraints.fill = GridBagConstraints.HORIZONTAL; @@ -983,6 +987,9 @@ Return(); + normalpushField = AddSlider(oe.ctrlPanel, "Push", -10, 10, 0, -1); + Return(); + // oe.ctrlPanel.add(stepButton = new cButton("Step"), ObjEditor.aConstraints, oe.ctrlPanel.getComponentCount() - 2); // ObjEditor.aConstraints.gridx += 1; @@ -1446,7 +1453,7 @@ aConstraints.gridx += 1; aConstraints.gridwidth = ObjEditor.GRIDWIDTH; //aConstraints.weightx = 0; - ctrlPanel.add(colorField = new NumberSlider(0.001, 1, -0.1), aConstraints); + ctrlPanel.add(colorField = new NumberSlider(0.001, 1, -0.5), aConstraints); aConstraints.gridx = 0; aConstraints.gridy += 1; aConstraints.gridwidth = 1; @@ -1456,7 +1463,7 @@ aConstraints.fill = GridBagConstraints.HORIZONTAL; aConstraints.gridx += 1; aConstraints.gridwidth = ObjEditor.GRIDWIDTH; - ctrlPanel.add(modulationField = new NumberSlider(0.001, 1, -0.1), aConstraints); + ctrlPanel.add(modulationField = new NumberSlider(0.001, 1, -0.5), aConstraints); aConstraints.gridx = 0; aConstraints.gridy += 1; aConstraints.gridwidth = 1; @@ -1466,7 +1473,7 @@ aConstraints.fill = GridBagConstraints.HORIZONTAL; aConstraints.gridx += 1; aConstraints.gridwidth = ObjEditor.GRIDWIDTH; - ctrlPanel.add(textureField = new NumberSlider(0.001, 1, -0.1), aConstraints); + ctrlPanel.add(textureField = new NumberSlider(0.001, 1, -0.5), aConstraints); aConstraints.gridx = 0; aConstraints.gridy += 1; aConstraints.gridwidth = 1; @@ -1476,7 +1483,7 @@ aConstraints.fill = GridBagConstraints.HORIZONTAL; aConstraints.gridx += 1; aConstraints.gridwidth = ObjEditor.GRIDWIDTH; - ctrlPanel.add(anisoField = new NumberSlider(0.001, 1, -0.1), aConstraints); + ctrlPanel.add(anisoField = new NumberSlider(0.001, 1, -0.5), aConstraints); aConstraints.gridx = 0; aConstraints.gridy += 1; aConstraints.gridwidth = 1; @@ -1486,7 +1493,7 @@ aConstraints.fill = GridBagConstraints.HORIZONTAL; aConstraints.gridx += 1; aConstraints.gridwidth = ObjEditor.GRIDWIDTH; - ctrlPanel.add(anisoVField = new NumberSlider(0.001, 1, -0.1), aConstraints); + ctrlPanel.add(anisoVField = new NumberSlider(0.001, 1, -0.5), aConstraints); aConstraints.gridx = 0; aConstraints.gridy += 1; aConstraints.gridwidth = 1; @@ -1555,7 +1562,7 @@ aConstraints.fill = GridBagConstraints.HORIZONTAL; aConstraints.gridx += 1; aConstraints.gridwidth = ObjEditor.GRIDWIDTH; - ctrlPanel.add(subsurfaceField = new NumberSlider(0.001, 1, -0.1), aConstraints); + ctrlPanel.add(subsurfaceField = new NumberSlider(0.001, 1, -0.5), aConstraints); aConstraints.gridx = 0; aConstraints.gridy += 1; aConstraints.gridwidth = 1; @@ -1624,7 +1631,7 @@ aConstraints.fill = GridBagConstraints.HORIZONTAL; aConstraints.gridx += 1; aConstraints.gridwidth = ObjEditor.GRIDWIDTH; - ctrlPanel.add(metalnessField = new NumberSlider(0.001, 1, -0.1), aConstraints); + ctrlPanel.add(metalnessField = new NumberSlider(0.001, 1, -0.5), aConstraints); aConstraints.gridx = 0; aConstraints.gridy += 1; aConstraints.gridwidth = 1; @@ -1695,7 +1702,7 @@ aConstraints.fill = GridBagConstraints.HORIZONTAL; aConstraints.gridx += 1; aConstraints.gridwidth = ObjEditor.GRIDWIDTH; - ctrlPanel.add(opacityField = new NumberSlider(0.001, 1, -0.1), aConstraints); + ctrlPanel.add(opacityField = new NumberSlider(0.001, 1, -0.5), aConstraints); aConstraints.gridx = 0; aConstraints.gridy += 1; aConstraints.gridwidth = 1; @@ -3549,7 +3556,13 @@ //System.out.println("PARENT = " + parent); //if (parent != null) // parent.applySelf(); - refreshContents(); + if (e.getSource() == normalpushField) + { + objEditor.refreshContents(); + //Refresh(); + } + else + refreshContents(); // ??? client.refreshEditWindow(); } //else @@ -3561,7 +3574,7 @@ //group.name = nameField.getText(); //objEditor.applySelf(); - assert (objEditor == this); + // OCT2018: assert (objEditor == this); if (copy.selection == null || copy.selection.size() == 0) //super.applySelf() ; else @@ -3585,6 +3598,9 @@ objEditor.copy = keep; } } + + if (normalpushField != null) + copy.NORMALPUSH = (float)normalpushField.getFloat()/1000; } void SnapObject() @@ -4629,4 +4645,6 @@ NumberSlider opacityPowerField; JTree jTree; //ObjectUI parent; + + NumberSlider normalpushField; } diff --git a/Object3D.java b/Object3D.java index f6cf69b..8a39641 100644 --- a/Object3D.java +++ b/Object3D.java @@ -21,6 +21,19 @@ ScriptNode scriptnode; + void InitOthers() + { + if (projectedVertices == null || projectedVertices.length <= 2) + { + projectedVertices = new Object3D.cVector2[3]; + } + for (int i = 0; i < 3; i++) + { + projectedVertices[i] = new cVector2(); // Others + } + projectedVertices[0].x = 100; // bump + } + void MinMax(cVector minima, cVector maxima) { for (int xyz = 0; xyz < 3; xyz++) @@ -295,6 +308,8 @@ boolean random = false; boolean speedup = false; boolean rewind = false; + + float NORMALPUSH = 0; Object3D support; @@ -779,7 +794,10 @@ // factor = CameraPane.STEP; // } - if (marked && CameraPane.isLIVE() && live && CameraPane.drawMode == CameraPane.SHADOW && currentframe != CameraPane.framecount) + if (marked && CameraPane.isLIVE() && live && + //TEMP21aug2018 + CameraPane.drawMode == CameraPane.SHADOW && + currentframe != CameraPane.framecount) { currentframe = CameraPane.framecount; @@ -2130,15 +2148,8 @@ if (/*parent != null &&*/ material == null) { material = new cMaterial(GetMaterial()); - if (projectedVertices == null || projectedVertices.length <= 2) - { - projectedVertices = new Object3D.cVector2[3]; - } - for (int i = 0; i < 3; i++) - { - projectedVertices[i] = new cVector2(); // Others - } - projectedVertices[0].x = 100; // bump + + InitOthers(); if (this instanceof Camera) { @@ -4161,6 +4172,22 @@ } } + void RepairShadow() + { + if (blockloop) + return; + + if (this.material != null) + this.InitOthers(); + + for (int i=0; i<Size(); i++) + { + blockloop = true; + get(i).RepairShadow(); + blockloop = false; + } + } + void RepairTexture() { if (this instanceof FileObject || blockloop) @@ -5958,7 +5985,7 @@ javax.media.opengl.GL gl = display.GetGL(); - if (CameraPane.BOXMODE) // || CameraPane.movingcamera) + if (CameraPane.BOXMODE && !selected) // || CameraPane.movingcamera) { int fc = bRep.FaceCount(); int vc = bRep.VertexCount(); @@ -6699,13 +6726,26 @@ gl.glNormal3f((float) v2.x, (float) v2.y, (float) v2.z); } + // P + float x = (float)pv.x; + float y = (float)pv.y; + float z = (float)pv.z; + if (hasnorm) { // if (!pv.norm.normalized()) // assert(pv.norm.normalized()); //System.out.println("normalp = " + pv.norm.x + ", " + pv.norm.y + ", " + pv.norm.z); - gl.glNormal3f((float) pv.norm.x, (float) pv.norm.y, (float) pv.norm.z); + float nx = (float)pv.norm.x; + float ny = (float)pv.norm.y; + float nz = (float)pv.norm.z; + + x += nx * NORMALPUSH; + y += ny * NORMALPUSH; + z += nz * NORMALPUSH; + + gl.glNormal3f(nx, ny, nz); } gl.glColor4f(pv.AO, pv.AO, pv.AO, 1); SetColor(display, pv); @@ -6716,13 +6756,28 @@ else gl.glTexCoord2f((float) pv.s, (float) pv.t); //System.out.println("vertexp = " + pv.x + ", " + pv.y + ", " + pv.z); - gl.glVertex3f((float) pv./*pos.*/x, (float) pv./*pos.*/y, (float) pv./*pos.*/z); + + gl.glVertex3f(x, y, z); + + // Q + x = (float)qv.x; + y = (float)qv.y; + z = (float)qv.z; + // Print(pv); if (hasnorm) { // assert(qv.norm.normalized()); //System.out.println("normalq = " + qv.norm.x + ", " + qv.norm.y + ", " + qv.norm.z); - gl.glNormal3f((float) qv.norm.x, (float) qv.norm.y, (float) qv.norm.z); + float nx = (float)qv.norm.x; + float ny = (float)qv.norm.y; + float nz = (float)qv.norm.z; + + x += nx * NORMALPUSH; + y += ny * NORMALPUSH; + z += nz * NORMALPUSH; + + gl.glNormal3f(nx, ny, nz); } //System.out.println("vertexq = " + qv.s + ", " + qv.t); // boolean locked = false; @@ -6746,16 +6801,31 @@ // } gl.glColor4f(qv.AO, qv.AO, qv.AO, 1); SetColor(display, qv); + + gl.glVertex3f(x, y, z); //gl.glColor4f(r, g, b, 1); //gl.glColor4f(qv.boundary, qv.boundary, qv.boundary, 1); //System.out.println("vertexq = " + qv.x + ", " + qv.y + ", " + qv.z); - gl.glVertex3f((float) qv./*pos.*/x, (float) qv./*pos.*/y, (float) qv./*pos.*/z); // Print(qv); + + // R + x = (float)rv.x; + y = (float)rv.y; + z = (float)rv.z; + if (hasnorm) { // assert(rv.norm.normalized()); //System.out.println("normalr = " + rv.norm.x + ", " + rv.norm.y + ", " + rv.norm.z); - gl.glNormal3f((float) rv.norm.x, (float) rv.norm.y, (float) rv.norm.z); + float nx = (float)rv.norm.x; + float ny = (float)rv.norm.y; + float nz = (float)rv.norm.z; + + x += nx * NORMALPUSH; + y += ny * NORMALPUSH; + z += nz * NORMALPUSH; + + gl.glNormal3f(nx, ny, nz); } // if ((dot&4) == 0) @@ -6776,7 +6846,7 @@ //gl.glColor4f(r, g, b, 1); //gl.glColor4f(rv.boundary, rv.boundary, rv.boundary, 1); //System.out.println("vertexr = " + rv.x + ", " + rv.y + ", " + rv.z); - gl.glVertex3f((float) rv./*pos.*/x, (float) rv./*pos.*/y, (float) rv./*pos.*/z); + gl.glVertex3f(x, y, z); // Print(rv); //gl.glEnd(); } @@ -8163,6 +8233,8 @@ { Object3D targ = this; + targ.NORMALPUSH = obj.NORMALPUSH; + if (obj.material != null) { if ((mask&MATERIAL)!=0) // ==(COLOR|MATERIAL)) diff --git a/ScriptNode.java b/ScriptNode.java index 6e25865..1315df0 100644 --- a/ScriptNode.java +++ b/ScriptNode.java @@ -972,25 +972,25 @@ if (command.equals("targetx")) { - ((Mocap) object).targetx = Float.parseFloat(strs[index+2]); + ((Mocap) object).targetdirx = Float.parseFloat(strs[index+2]); return; } if (command.equals("targetz")) { - ((Mocap) object).targetz = Float.parseFloat(strs[index+2]); + ((Mocap) object).targetdirz = Float.parseFloat(strs[index+2]); return; } if (command.equals("goalx")) { - ((Mocap) object).goalx = Float.parseFloat(strs[index+2]); + ((Mocap) object).goalposx = Float.parseFloat(strs[index+2]); return; } if (command.equals("goalz")) { - ((Mocap) object).goalz = Float.parseFloat(strs[index+2]); + ((Mocap) object).goalposz = Float.parseFloat(strs[index+2]); return; } diff --git a/Texture.java b/Texture.java index 8f0cc1d..23134d0 100644 --- a/Texture.java +++ b/Texture.java @@ -10,7 +10,7 @@ public class Texture extends Composite implements java.io.Serializable { // deprecated due to serial problems - static final long serialVersionUID = // -5280151442948961597L; // new java + static final long serialVersionUID = //-5280151442948961597L; // new java 7695543694999681408L; // old java !!! // default = -8076744133104150348L diff --git a/cSpring.java b/cSpring.java index 2986693..445f1ac 100644 --- a/cSpring.java +++ b/cSpring.java @@ -82,7 +82,7 @@ // timestep double timestep = 1; - double normalpusH = 0; // 1; + double normalpush = 0; // 1; static float H0 = 1E1f; // aucune importance... // mass double M = 1; @@ -967,6 +967,7 @@ for (int i = 0; i < allNodes.size(); i++) { DynamicNode dn = allNodes.get(i); + dn.linked = false; dn.closestpoint = null; } } @@ -1416,6 +1417,7 @@ //transient double rotangle; // Z of axis transient boolean reverse = false; + transient boolean linked = false; transient Vertex closestpoint = null; //Point3D lastForce = new Point3D(); @@ -1491,6 +1493,11 @@ otherForce.add(f.forceOn(this)); } } + } + + if (Double.isNaN(springForce.y)) + { + springForce.x = springForce.y = springForce.z = 0; } } @@ -2339,28 +2346,7 @@ return this; } - class Avoider extends Force - { - static final long serialVersionUID = -8657094699711594990L; - - Avoider() - { - } - - Avoider(Object3D col) - { - SetAvoider(col); - } - - void SetParameter(int index, double value) - { - parameters.setElementAt(new Double(value), index); - } - - void SetAvoider(Object3D col) - { - avoider = col; - } + Object3D avoider; void ResetGlobalTransform() { @@ -2372,10 +2358,6 @@ transient double[][] toRoot; // = new double[4][4]; - //Vector<Vertex> sortedcollider; - Object3D avoider; - Vector<Double> parameters = new Vector<Double>(); // serial issue - Vertex ClosestPoint(Vector<Vertex> collider, DynamicNode N, int startindex, int endindex, int sortaxis) { if (startindex == endindex) @@ -2469,7 +2451,8 @@ for (int i=collider.size(); --i>=0;) { - if (collider.get(i).norm.dot(((Vertex)N.position).norm) < 0) + // Why? 3 dec 2018 + if (collider.get(i).norm.dot(((Vertex)N.position).norm) < 0.5) continue; temp.set(N.position); @@ -2487,43 +2470,24 @@ } } - return cp; + return mindist2 < 1 ? cp : null; } - Point3D forceOn(DynamicNode N) + class Avoider extends Force + { + static final long serialVersionUID = -8657094699711594990L; + + Avoider() { - force.x = 0; - force.y = 0; - force.z = 0; - - if (avoider.transientrep == null) - avoider.Revert(); - - if (avoider.transientrep == null || avoider.transientrep.VertexCount() == 0 || avoider.transientrep.trimmed) - return force; - - ResetGlobalTransform(); - if (N.closestpoint == null) - { - //avoider.bRep.GetVertex(0); // "sort" - - ResetGlobalTransform(); - - N.closestpoint = ClosestPoint(avoider.transientrep./*sortedV*/vertices, N, 0,avoider.transientrep./*sortedV*/vertices.size(), 0); - - if (N.closestpoint == null) // ???? - return force; - } - - if (avoider == This()) - { - // good but must freeze the order first... not really... - // if (cp.index < ((Vertex)N.position).index) - // return force; - } - - if (normalpusH != 0) // && cp == null /*???*/) // speed == 0) - { + } + + Avoider(Object3D col) + { + SetAvoider(col); + } + + void Avoidance(DynamicNode N) + { temp.set(N.position); if (avoider != This()) { @@ -2531,16 +2495,16 @@ temp2.mul(0.001); temp.sub(temp2); // push outside because of mesh artifacts } - + vect1.set(N.closestpoint); - + LA.xformPos(vect1,toRoot,vect1); //avoider.TransformToWorld(vect1, vect1); - + temp.sub(vect1); - + double distance = Math.sqrt(temp.length2()); - + if (distance < 0.01) { temp2.set(N.closestpoint.norm); @@ -2554,9 +2518,98 @@ if (IsAutoFreeze()) dot = -dot; - temp.mul(normalpusH/*/distance*/*-dot/Math.sqrt(distance)); + temp.mul(normalpush/*/distance*/*-dot/Math.sqrt(distance)); force.add(temp); } + } + + void Attraction(DynamicNode N) + { + temp.set(N.position); + if (avoider != This()) + { + temp2.set(N.closestpoint.norm); + temp2.mul(0.001); + temp.sub(temp2); // push outside because of mesh artifacts + } + + vect1.set(N.closestpoint); + + LA.xformPos(vect1,toRoot,vect1); + //avoider.TransformToWorld(vect1, vect1); + + temp.sub(vect1); + + double distance = Math.sqrt(temp.length2()); + + //if (distance < 0.01) + { + temp2.set(N.closestpoint.norm); + double dot = temp2.dot(temp); + +// if (dot > 0) +// dot = 0; + + // normal pushing + temp.set(N.closestpoint.norm); +// if (IsAutoFreeze()) +// dot = -dot; + + temp.mul(normalpush/*/distance*/ * -dot * distance); + force.add(temp); + } + } + + void SetParameter(int index, double value) + { + parameters.setElementAt(new Double(value), index); + } + + void SetAvoider(Object3D col) + { + avoider = col; + } + + //Vector<Vertex> sortedcollider; + Vector<Double> parameters = new Vector<Double>(); // serial issue + + Point3D forceOn(DynamicNode N) + { + force.x = 0; + force.y = 0; + force.z = 0; + + if (avoider.transientrep == null) + avoider.Revert(); + + if (avoider.transientrep == null || avoider.transientrep.VertexCount() == 0 || avoider.transientrep.trimmed) + return force; + + ResetGlobalTransform(); + if (!N.linked) + { + //avoider.bRep.GetVertex(0); // "sort" + + ResetGlobalTransform(); + + N.closestpoint = ClosestPoint(avoider.transientrep.vertices, N, 0,avoider.transientrep.vertices.size(), 0); + N.linked = true; + } + + if (avoider == This()) + { + // good but must freeze the order first... not really... + // if (cp.index < ((Vertex)N.position).index) + // return force; + } + + if (normalpush != 0) // && cp == null /*???*/) // speed == 0) + { + if (N.closestpoint == null) + return force; + + //Avoidance(N); + Attraction(N); } if (parameters.size() > 0) @@ -2590,6 +2643,7 @@ totalforce = new Point3D(); totalforce.set(0,0,0); + if (forces.size() == 0) totalforce.set(super.forceOn(N)); @@ -2660,7 +2714,7 @@ force.y = 0; force.z = 0; - if (normalpusH != 0) // speed == 0) // Now normal force + if (normalpush != 0) // speed == 0) // Now normal force { // temp.set(N.position); // temp.sub(Phys.reference); @@ -2668,7 +2722,7 @@ // normal pushing temp.set(N.normal); - temp.mul(normalpusH/distance); + temp.mul(normalpush/distance); force.add(temp); } @@ -2900,6 +2954,7 @@ return force; } } + static int TABLESAC = 1024; static double[] tablesac = new double[TABLESAC]; @@ -2993,6 +3048,40 @@ // mass = M; } // ??? + if (avoider != null) + { + if (avoider.transientrep == null) + avoider.Revert(); + + if (avoider.transientrep == null || avoider.transientrep.VertexCount() == 0 || avoider.transientrep.trimmed) + return force; + + ResetGlobalTransform(); + if (!N.linked) + { + //avoider.bRep.GetVertex(0); // "sort" + + //ResetGlobalTransform(); + + N.closestpoint = ClosestPoint(avoider.transientrep.vertices, N, 0,avoider.transientrep.vertices.size(), 0); + N.linked = true; + } + + if (N.closestpoint != null) + { + temp.set(N.position); + vect1.set(N.closestpoint); + LA.xformPos(vect1,toRoot,vect1); + temp.sub(vect1); + + temp2.set(N.closestpoint.norm); + double dot = temp2.dot(temp); + + if (dot < 0) + mass = Float.NaN; + } + } + force.x = 0; force.y = (float) (-acceleration * mass); force.z = 0; // -acceleration * mass * 1000 * Math.cos(time/234.0 + framecount*100); // (Math.random()*2 - 1); // @@ -3189,7 +3278,7 @@ } if (false) // isHandle) { - double K = Math.exp(-displacement*normalpusH); + double K = Math.exp(-displacement*normalpush); magnitude /= (displacement*(1-K) + K); } diff --git a/cSpringEditor.java b/cSpringEditor.java index 50018df..d94eeeb 100644 --- a/cSpringEditor.java +++ b/cSpringEditor.java @@ -133,7 +133,7 @@ // ObjEditor.aConstraints.gridwidth = 1; // //ObjEditor.aConstraints.fill = 0; // ObjEditor.aConstraints.gridx -= 1; - normalField = AddSlider(oe.ctrlPanel, "Normal:", 0, 20.0, Math.log(spring.normalpusH+1), 1); + normalField = AddSlider(oe.ctrlPanel, "Normal:", 0, 20.0, Math.log(spring.normalpush+1), 1); Return(); /**/ @@ -472,7 +472,11 @@ spring.W.AddForce(spring.new Avoider(GetEditor().copy.selection.get(0))); } -// else + else + { + if (spring.W instanceof cSpring.ActingForces) + ((cSpring.ActingForces)spring.W).forces.clear(); + } /* if (spring.Phys == null) // || spring.IsAutoFreeze()) spring.InitPhysics(); @@ -564,7 +568,7 @@ spring.K = k; spring.M = m; spring.G.acceleration = g; - spring.normalpusH = d; // * Math.sqrt(m/k); + spring.normalpush = d; // * Math.sqrt(m/k); spring.limit = L; spring.restlengthFactor = t; spring.W.wind = v; -- Gitblit v1.6.2